[builder] Add library queue to manage cloned environments
This commit is contained in:
@@ -7,6 +7,8 @@ from SCons.Script import DefaultEnvironment, Environment
|
||||
|
||||
env: Environment = DefaultEnvironment()
|
||||
board: PlatformBoardConfig = env.BoardConfig()
|
||||
queue = env.AddLibraryQueue("beken-72xx")
|
||||
env.ConfigureFamily()
|
||||
|
||||
ROOT_DIR = join("$SDK_DIR", "beken378")
|
||||
APP_DIR = join(ROOT_DIR, "app")
|
||||
@@ -36,7 +38,7 @@ SOC = env.Cfg("CFG_SOC_NAME")
|
||||
WPA_VERSION = "wpa_supplicant_2_9" if env.Cfg("CFG_USE_WPA_29") else "hostapd-2.5"
|
||||
|
||||
# Flags
|
||||
env.Append(
|
||||
queue.AppendPublic(
|
||||
CCFLAGS=[
|
||||
"-mcpu=arm968e-s",
|
||||
"-march=armv5te",
|
||||
@@ -119,8 +121,9 @@ srcs_core = []
|
||||
|
||||
# Fix for BK7231T's bootloader compatibility
|
||||
if board.get("build.bkboot_version") == "1.0.5-bk7231s":
|
||||
env.Append(CPPDEFINES=[("CFG_SUPPORT_BOOTLOADER", "1")])
|
||||
env.AddLibrary(
|
||||
# this has to be public, so that fixups/intc.c sees it
|
||||
queue.AppendPublic(CPPDEFINES=[("CFG_SUPPORT_BOOTLOADER", "1")])
|
||||
queue.AddLibrary(
|
||||
name="bdk_boot",
|
||||
base_dir="$FAMILY_DIR/base/fixups",
|
||||
srcs=["+<boot_handlers_105_bk7231s.S>"],
|
||||
@@ -129,7 +132,7 @@ else:
|
||||
srcs_core.append("+<driver/entry/boot_handlers.S>")
|
||||
|
||||
# Sources - from framework-beken-bdk/beken378/beken_src.mk
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_core",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
@@ -151,7 +154,7 @@ env.AddLibrary(
|
||||
)
|
||||
|
||||
# Sources - app module
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_app",
|
||||
base_dir=APP_DIR,
|
||||
srcs=[
|
||||
@@ -171,7 +174,7 @@ env.AddLibrary(
|
||||
)
|
||||
|
||||
# Sources - drivers
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_driver",
|
||||
base_dir=DRIVER_DIR,
|
||||
srcs=[
|
||||
@@ -228,7 +231,7 @@ env.AddLibrary(
|
||||
)
|
||||
|
||||
# Sources - functional components
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_func",
|
||||
base_dir=FUNC_DIR,
|
||||
srcs=[
|
||||
@@ -292,7 +295,7 @@ env.AddLibrary(
|
||||
)
|
||||
|
||||
# Sources - FreeRTOS
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_freertos_thumb",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
@@ -302,7 +305,7 @@ env.AddLibrary(
|
||||
"+<os/*>",
|
||||
],
|
||||
)
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_freertos_arm",
|
||||
base_dir="$SDK_DIR",
|
||||
srcs=[
|
||||
@@ -322,10 +325,10 @@ env.AddLibrary(
|
||||
)
|
||||
|
||||
# Sources - lwIP
|
||||
env.AddExternalLibrary("lwip", port="bdk")
|
||||
queue.AddExternalLibrary("lwip", port="bdk")
|
||||
|
||||
# Sources - mbedTLS 2.6.0
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_mbedtls",
|
||||
base_dir=join(FUNC_DIR, "mbedtls"),
|
||||
srcs=[
|
||||
@@ -349,7 +352,7 @@ env.AddLibrary(
|
||||
|
||||
# Sources - chip-specific drivers
|
||||
if SOC in [SOC_BK7231U, SOC_BK7251]:
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_driver_spi",
|
||||
base_dir=join(DRIVER_DIR, "spi"),
|
||||
srcs=[
|
||||
@@ -359,7 +362,7 @@ if SOC in [SOC_BK7231U, SOC_BK7251]:
|
||||
],
|
||||
)
|
||||
if SOC in [SOC_BK7231N]:
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_driver_spi",
|
||||
base_dir=join(DRIVER_DIR, "spi"),
|
||||
srcs=[
|
||||
@@ -369,7 +372,7 @@ if SOC in [SOC_BK7231N]:
|
||||
],
|
||||
)
|
||||
if SOC in [SOC_BK7251]:
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_bk7251",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
@@ -386,7 +389,7 @@ if SOC in [SOC_BK7251]:
|
||||
|
||||
# Sources - enabled through config
|
||||
if env.Cfg("CFG_SDIO"):
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_driver_sdio",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
@@ -395,7 +398,7 @@ if env.Cfg("CFG_SDIO"):
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_BK_AWARE"):
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_driver_sdio",
|
||||
base_dir="$SDK_DIR",
|
||||
srcs=[
|
||||
@@ -407,7 +410,7 @@ if env.Cfg("CFG_BK_AWARE"):
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_USE_SDCARD_HOST"):
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_func_fatfs",
|
||||
base_dir=join(FUNC_DIR, "fatfs"),
|
||||
srcs=[
|
||||
@@ -419,7 +422,7 @@ if env.Cfg("CFG_USE_SDCARD_HOST"):
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_WPA3"):
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_wolfssl",
|
||||
base_dir=join(FUNC_DIR, "wolfssl"),
|
||||
srcs=[
|
||||
@@ -437,7 +440,7 @@ if env.Cfg("CFG_WPA3"):
|
||||
if env.Cfg("CFG_SUPPORT_BLE") and env.Cfg("CFG_BLE_VERSION") == env.Cfg(
|
||||
"BLE_VERSION_4_2"
|
||||
):
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_ble_4_2",
|
||||
base_dir=join(DRIVER_DIR, "ble"),
|
||||
srcs=[
|
||||
@@ -457,7 +460,7 @@ if env.Cfg("CFG_SUPPORT_BLE") and env.Cfg("CFG_BLE_VERSION") == env.Cfg(
|
||||
if env.Cfg("CFG_SUPPORT_BLE") and env.Cfg("CFG_BLE_VERSION") == env.Cfg(
|
||||
"BLE_VERSION_5_x"
|
||||
):
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_ble_5_x",
|
||||
base_dir=join(DRIVER_DIR, "ble_5_x_rw"),
|
||||
srcs=[
|
||||
@@ -479,7 +482,7 @@ if env.Cfg("CFG_SUPPORT_BLE") and env.Cfg("CFG_BLE_VERSION") == env.Cfg(
|
||||
],
|
||||
)
|
||||
if env.Cfg("ATSVR_CFG"):
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_atsvr",
|
||||
base_dir=join(FUNC_DIR, "at_server"),
|
||||
srcs=[
|
||||
@@ -491,7 +494,7 @@ if env.Cfg("ATSVR_CFG"):
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_USB") or env.Cfg("CFG_USE_SDCARD_HOST"):
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name="bdk_driver_usb",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
@@ -504,7 +507,7 @@ if env.Cfg("CFG_USB") or env.Cfg("CFG_USE_SDCARD_HOST"):
|
||||
)
|
||||
|
||||
# Libs & linker config
|
||||
env.Append(
|
||||
queue.AppendPublic(
|
||||
LIBPATH=[
|
||||
join("$SDK_DIR", "beken378", "lib"),
|
||||
join("$SDK_DIR", "beken378", "func", "airkiss"),
|
||||
@@ -549,7 +552,7 @@ rbl_offs = to_offset(app_size) - 102
|
||||
env.Replace(FLASH_RBL_OFFSET=f"0x{app_offs + rbl_offs:06X}")
|
||||
|
||||
# Build all libraries
|
||||
env.BuildLibraries()
|
||||
queue.BuildLibraries()
|
||||
|
||||
# Main firmware outputs and actions
|
||||
env.Replace(
|
||||
|
||||
@@ -9,17 +9,67 @@ from SCons.Script import DefaultEnvironment, Environment
|
||||
# Let everyone know we're using the Arduino framework
|
||||
env: Environment = DefaultEnvironment()
|
||||
env["ARDUINO"] = True
|
||||
family: Family = env["FAMILY_OBJ"]
|
||||
|
||||
# Add base cores' sources first
|
||||
env.SConscript("base.py")
|
||||
|
||||
# Build a safe environment for this script
|
||||
queue = env.AddLibraryQueue("arduino", prepend_includes=True)
|
||||
|
||||
# Add sources common among all families
|
||||
env.AddCoreSources(
|
||||
queue=queue,
|
||||
name="common_arduino",
|
||||
path=join("$COMMON_DIR", "arduino", "src"),
|
||||
)
|
||||
env.AddArduinoLibraries(
|
||||
queue=queue,
|
||||
name="common_arduino",
|
||||
path=join("$COMMON_DIR", "arduino", "libraries"),
|
||||
)
|
||||
# Add sources for this family and each parent
|
||||
found = False
|
||||
for f in family.inheritance:
|
||||
code = f"{f.code}_arduino"
|
||||
path = join("$CORES_DIR", f.name, "arduino")
|
||||
|
||||
found = found or env.AddCoreSources(queue, name=code, path=join(path, "src"))
|
||||
env.AddArduinoLibraries(queue, name=code, path=join(path, "libraries"))
|
||||
|
||||
if f.short_name:
|
||||
env.Prepend(CPPDEFINES=[(f"ARDUINO_ARCH_{f.short_name}", "1")])
|
||||
if f.code:
|
||||
env.Prepend(CPPDEFINES=[(f"ARDUINO_ARCH_{f.code.upper()}", "1")])
|
||||
|
||||
# Fail if Arduino core wasn't found
|
||||
if not found:
|
||||
click.secho(
|
||||
f"Platform '{family.name}' doesn't support Arduino framework - "
|
||||
"the Arduino core source files are absent.",
|
||||
fg="red",
|
||||
)
|
||||
exit(1)
|
||||
|
||||
# Sources - ArduinoCore-API
|
||||
queue.AddExternalLibrary("arduino_api")
|
||||
|
||||
# Sources - board variant
|
||||
queue.AddLibrary(
|
||||
name="board_${VARIANT}",
|
||||
base_dir="$BOARD_DIR",
|
||||
srcs=[
|
||||
"+<variant.cpp>",
|
||||
],
|
||||
# not adding includes since they're added with the base core
|
||||
)
|
||||
|
||||
# Flags & linker options
|
||||
env.Append(
|
||||
queue.AppendPublic(
|
||||
CPPDEFINES=[
|
||||
("LIBRETUYA_ARDUINO", 1),
|
||||
("ARDUINO", 10812),
|
||||
("ARDUINO_SDK", 1),
|
||||
("ARDUINO_ARCH_${FAMILY_CODE}", 1),
|
||||
],
|
||||
LINKFLAGS=[
|
||||
"--specs=nosys.specs",
|
||||
@@ -35,47 +85,5 @@ env.Append(
|
||||
],
|
||||
)
|
||||
|
||||
family: Family = env["FAMILY_OBJ"]
|
||||
|
||||
# Add common sources among all families
|
||||
env.AddCoreSources(
|
||||
name="common_arduino",
|
||||
path=join("$COMMON_DIR", "arduino", "src"),
|
||||
)
|
||||
env.AddArduinoLibraries(
|
||||
name="common_arduino",
|
||||
path=join("$COMMON_DIR", "arduino", "libraries"),
|
||||
)
|
||||
# Add sources for this family and each parent
|
||||
found = False
|
||||
for f in family.inheritance:
|
||||
code = f"{f.code}_arduino"
|
||||
path = join("$CORES_DIR", f.name, "arduino")
|
||||
# Add libraries first, to put the include paths after core sources
|
||||
env.AddArduinoLibraries(name=code, path=join(path, "libraries"))
|
||||
found = found or env.AddCoreSources(name=code, path=join(path, "src"))
|
||||
|
||||
# Fail if Arduino core wasn't found
|
||||
if not found:
|
||||
click.secho(
|
||||
f"Platform '{family.name}' doesn't support Arduino framework - "
|
||||
"the Arduino core source files are absent.",
|
||||
fg="red",
|
||||
)
|
||||
exit(1)
|
||||
|
||||
# Sources - ArduinoCore-API
|
||||
env.AddExternalLibrary("arduino_api")
|
||||
|
||||
# Sources - board variant
|
||||
env.AddLibrary(
|
||||
name="board_${VARIANT}",
|
||||
base_dir="$BOARD_DIR",
|
||||
srcs=[
|
||||
"+<variant.cpp>",
|
||||
],
|
||||
# not adding includes since they're added in base.py
|
||||
)
|
||||
|
||||
# Build all libraries
|
||||
env.BuildLibraries()
|
||||
queue.BuildLibraries()
|
||||
|
||||
@@ -12,53 +12,10 @@ from SCons.Script import DefaultEnvironment, Environment
|
||||
env: Environment = DefaultEnvironment()
|
||||
board: PlatformBoardConfig = env.BoardConfig()
|
||||
platform: PlatformBase = env.PioPlatform()
|
||||
|
||||
# Environment variables, include paths, etc.
|
||||
family: Family = env.ConfigureEnvironment(platform, board)
|
||||
# Flash layout defines
|
||||
env.AddFlashLayout(board)
|
||||
|
||||
# Flags & linker options
|
||||
env.Append(
|
||||
CFLAGS=[
|
||||
"-Werror=implicit-function-declaration",
|
||||
],
|
||||
CPPDEFINES=[
|
||||
("LIBRETUYA", 1),
|
||||
("LT_VERSION", env.ReadLTVersion(platform.get_dir(), platform.version)),
|
||||
("LT_BOARD", "${VARIANT}"),
|
||||
("F_CPU", board.get("build.f_cpu")),
|
||||
("MCU", "${MCU}"),
|
||||
("FAMILY", "F_${FAMILY}"),
|
||||
],
|
||||
CPPPATH=[
|
||||
"$BOARD_DIR",
|
||||
],
|
||||
LINKFLAGS=[
|
||||
'"-Wl,-Map=' + join("$BUILD_DIR", "${PROGNAME}.map") + '"',
|
||||
],
|
||||
LIBS=[
|
||||
"stdc++",
|
||||
"supc++",
|
||||
],
|
||||
)
|
||||
|
||||
# Build a core list to add sources, flags, etc.
|
||||
cores = {
|
||||
"common": "$COMMON_DIR",
|
||||
}
|
||||
# Configure each family first (add CPP defines)
|
||||
for f in family.inheritance:
|
||||
cores[f.code] = env.AddFamily(f)
|
||||
|
||||
# Add fixups & config for each core
|
||||
for name, path in cores.items():
|
||||
env.AddCoreConfig(path=join(path, "base"))
|
||||
if "ARDUINO" in env:
|
||||
env.AddCoreConfig(path=join(path, "arduino", "src"))
|
||||
family: Family = env["FAMILY_OBJ"]
|
||||
|
||||
# Include SDK builder scripts
|
||||
# The script will call BuildLibraries(safe=True) to secure the include paths
|
||||
# No environment options that follow later will be considered
|
||||
found = False
|
||||
for f in family.inheritance:
|
||||
try:
|
||||
@@ -75,14 +32,50 @@ if not found:
|
||||
)
|
||||
exit(1)
|
||||
|
||||
# Build a safe environment for this script
|
||||
queue = env.AddLibraryQueue("base", prepend_includes=True)
|
||||
# Add sources & include paths for each core
|
||||
for name, path in cores.items():
|
||||
env.AddCoreSources(name=name, path=join(path, "base"))
|
||||
env.AddCoreSources(queue, name="common", path=join("$COMMON_DIR", "base"))
|
||||
for f in family.inheritance:
|
||||
env.AddCoreSources(queue, name=f.code, path=join("$CORES_DIR", f.name, "base"))
|
||||
|
||||
if f.short_name:
|
||||
env.Prepend(CPPDEFINES=[(f"LT_{f.short_name}", "1")])
|
||||
if f.code:
|
||||
env.Prepend(CPPDEFINES=[(f"LT_{f.code.upper()}", "1")])
|
||||
env.Prepend(LIBPATH=[join("$CORES_DIR", f.name, "misc")])
|
||||
|
||||
# Sources - external libraries
|
||||
env.AddExternalLibrary("ltchiptool") # uf2ota source code
|
||||
env.AddExternalLibrary("flashdb")
|
||||
env.AddExternalLibrary("printf")
|
||||
queue.AddExternalLibrary("ltchiptool") # uf2ota source code
|
||||
queue.AddExternalLibrary("flashdb")
|
||||
queue.AddExternalLibrary("printf")
|
||||
|
||||
# Flags & linker options
|
||||
queue.AppendPublic(
|
||||
CFLAGS=[
|
||||
"-Werror=implicit-function-declaration",
|
||||
],
|
||||
CPPDEFINES=[
|
||||
("LIBRETUYA", 1),
|
||||
("LT_VERSION", env.ReadLTVersion(platform.get_dir(), platform.version)),
|
||||
("LT_BOARD", "${VARIANT}"),
|
||||
("F_CPU", board.get("build.f_cpu")),
|
||||
("MCU", "${MCU}"),
|
||||
("FAMILY", "F_${FAMILY}"),
|
||||
# Add flash layout defines created in env.AddFlashLayout()
|
||||
*env["FLASH_DEFINES"].items(),
|
||||
],
|
||||
CPPPATH=[
|
||||
"$BOARD_DIR",
|
||||
],
|
||||
LINKFLAGS=[
|
||||
'"-Wl,-Map=' + join("$BUILD_DIR", "${PROGNAME}.map") + '"',
|
||||
],
|
||||
LIBS=[
|
||||
"stdc++",
|
||||
"supc++",
|
||||
],
|
||||
)
|
||||
|
||||
# Build everything from the base core
|
||||
env.BuildLibraries()
|
||||
queue.BuildLibraries()
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
import sys
|
||||
|
||||
from platformio.platform.base import PlatformBase
|
||||
from platformio.platform.board import PlatformBoardConfig
|
||||
from SCons.Script import Default, DefaultEnvironment, Environment
|
||||
|
||||
env: Environment = DefaultEnvironment()
|
||||
platform: PlatformBase = env.PioPlatform()
|
||||
board: PlatformBoardConfig = env.BoardConfig()
|
||||
|
||||
# Utilities
|
||||
@@ -14,7 +16,7 @@ env.SConscript("utils/cores.py", exports="env")
|
||||
env.SConscript("utils/env.py", exports="env")
|
||||
env.SConscript("utils/flash.py", exports="env")
|
||||
env.SConscript("utils/libs-external.py", exports="env")
|
||||
env.SConscript("utils/libs.py", exports="env")
|
||||
env.SConscript("utils/libs-queue.py", exports="env")
|
||||
env.SConscript("utils/ltchiptool.py", exports="env")
|
||||
|
||||
# Firmware name
|
||||
@@ -38,6 +40,11 @@ env.Replace(
|
||||
SIZETOOL=prefix + "size",
|
||||
)
|
||||
|
||||
# Environment variables, include paths, etc.
|
||||
env.ConfigureEnvironment(platform, board)
|
||||
# Flash layout defines
|
||||
env.AddFlashLayout(board)
|
||||
|
||||
# Family builders details:
|
||||
# - call env.AddLibrary("lib name", "base dir", [sources]) to add lib sources
|
||||
# - call env.BuildLibraries() to build lib targets with safe envs
|
||||
|
||||
@@ -8,44 +8,40 @@ from SCons.Script import DefaultEnvironment, Environment
|
||||
env: Environment = DefaultEnvironment()
|
||||
|
||||
|
||||
def env_add_family(env: Environment, family: Family) -> str:
|
||||
if family.short_name:
|
||||
env.Prepend(CPPDEFINES=[(f"LT_{family.short_name}", "1")])
|
||||
if family.code:
|
||||
env.Prepend(CPPDEFINES=[(f"LT_{family.code.upper()}", "1")])
|
||||
path = join("$CORES_DIR", family.name)
|
||||
if not isdir(env.subst(path)):
|
||||
return path
|
||||
env.Prepend(
|
||||
LIBPATH=[join(path, "misc")],
|
||||
)
|
||||
return path
|
||||
|
||||
|
||||
def env_add_core_config(env: Environment, path: str) -> bool:
|
||||
if not isdir(env.subst(path)):
|
||||
return False
|
||||
def env_configure_family(env: Environment):
|
||||
env.Prepend(
|
||||
CPPPATH=[
|
||||
join("$COMMON_DIR", "base", "fixups"),
|
||||
join("$COMMON_DIR", "base", "config"),
|
||||
join("$COMMON_DIR", "base", "compat"),
|
||||
],
|
||||
)
|
||||
|
||||
family: Family = env["FAMILY_OBJ"]
|
||||
for f in family.inheritance:
|
||||
path = join("$CORES_DIR", f.name, "base")
|
||||
if not isdir(env.subst(path)):
|
||||
continue
|
||||
env.Prepend(
|
||||
CPPPATH=[
|
||||
join(path, "compat"),
|
||||
join(path, "config"),
|
||||
join(path, "fixups"),
|
||||
join(path, "config"),
|
||||
join(path, "compat"),
|
||||
],
|
||||
LIBPATH=[
|
||||
join(path, "fixups"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def env_add_core_sources(env: Environment, queue, name: str, path: str) -> bool:
|
||||
if not isdir(env.subst(path)):
|
||||
return False
|
||||
try:
|
||||
env.LoadDefines(join(path, "lt_defs.h"))
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
return True
|
||||
|
||||
|
||||
def env_add_core_sources(env: Environment, name: str, path: str) -> bool:
|
||||
if not isdir(env.subst(path)):
|
||||
return False
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name=f"core_{name}",
|
||||
base_dir=path,
|
||||
srcs=[
|
||||
@@ -69,10 +65,10 @@ def env_add_core_sources(env: Environment, name: str, path: str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def env_add_arduino_libraries(env: Environment, name: str, path: str) -> bool:
|
||||
def env_add_arduino_libraries(env: Environment, queue, name: str, path: str) -> bool:
|
||||
if not isdir(env.subst(path)):
|
||||
return False
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name=f"core_{name}_libraries",
|
||||
base_dir=path,
|
||||
srcs=[
|
||||
@@ -85,7 +81,6 @@ def env_add_arduino_libraries(env: Environment, name: str, path: str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
env.AddMethod(env_add_family, "AddFamily")
|
||||
env.AddMethod(env_add_core_config, "AddCoreConfig")
|
||||
env.AddMethod(env_configure_family, "ConfigureFamily")
|
||||
env.AddMethod(env_add_core_sources, "AddCoreSources")
|
||||
env.AddMethod(env_add_arduino_libraries, "AddArduinoLibraries")
|
||||
|
||||
@@ -21,13 +21,13 @@ def env_add_flash_layout(env: Environment, board):
|
||||
defines[f"FLASH_{name}_LENGTH"] = length
|
||||
fal_items += f"FAL_PART_TABLE_ITEM({name.lower()},{name})"
|
||||
flash_size = max(flash_size, int(offset, 16) + int(length, 16))
|
||||
defines["FLASH_LENGTH"] = flash_size
|
||||
defines["FLASH_LENGTH"] = f"0x{flash_size:06X}"
|
||||
# for "root" partition
|
||||
defines["FLASH_ROOT_OFFSET"] = 0
|
||||
defines["FLASH_ROOT_LENGTH"] = flash_size
|
||||
defines["FLASH_ROOT_OFFSET"] = "0x000000"
|
||||
defines["FLASH_ROOT_LENGTH"] = f"0x{flash_size:06X}"
|
||||
# add partition table array
|
||||
defines["FAL_PART_TABLE"] = "{" + fal_items + "}"
|
||||
env.Append(CPPDEFINES=list(defines.items()))
|
||||
env.Replace(FLASH_DEFINES=defines)
|
||||
env.Replace(**defines)
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ platform: PlatformBase = env.PioPlatform()
|
||||
|
||||
|
||||
@dataclass
|
||||
class Library:
|
||||
class ExternalLibrary:
|
||||
package: str
|
||||
sources: List[str]
|
||||
includes: List[str]
|
||||
@@ -28,13 +28,14 @@ class Library:
|
||||
|
||||
def env_add_external_library(
|
||||
env: Environment,
|
||||
queue,
|
||||
name: str,
|
||||
port: Optional[str] = None,
|
||||
):
|
||||
if port:
|
||||
name += f"-{port}"
|
||||
external_libs = env["EXTERNAL_LIBS"]
|
||||
lib = Library(**external_libs[name])
|
||||
lib = ExternalLibrary(**external_libs[name])
|
||||
version = platform.versions.get(lib.package, None)
|
||||
|
||||
package: PackageItem = platform.pm.get_package(
|
||||
@@ -45,7 +46,7 @@ def env_add_external_library(
|
||||
f"Version '{version}' of library '{name}' ({lib.package}) is not installed"
|
||||
)
|
||||
|
||||
env.AddLibrary(
|
||||
queue.AddLibrary(
|
||||
name=name.replace("-", "_"),
|
||||
base_dir=package.path,
|
||||
srcs=lib.sources,
|
||||
|
||||
210
builder/utils/libs-queue.py
Normal file
210
builder/utils/libs-queue.py
Normal file
@@ -0,0 +1,210 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2023-02-28.
|
||||
|
||||
import fnmatch
|
||||
from dataclasses import InitVar, dataclass, field
|
||||
from glob import glob
|
||||
from os.path import isdir, join
|
||||
from typing import Dict, Generator, List, Optional, Tuple
|
||||
|
||||
from ltchiptool.util.dict import merge_dicts
|
||||
from SCons.Script import DefaultEnvironment, Environment
|
||||
|
||||
env: Environment = DefaultEnvironment()
|
||||
|
||||
|
||||
def add_base_dir(
|
||||
env: Environment,
|
||||
base_dir: str,
|
||||
expressions: List[str],
|
||||
subst: bool = False,
|
||||
):
|
||||
out = []
|
||||
for expr in expressions:
|
||||
if expr == False:
|
||||
# support '[cond] and [path]' logical expressions
|
||||
continue
|
||||
if expr[1] != "<" or expr[-1] != ">":
|
||||
raise ValueError(f"Not a valid glob: {expr}")
|
||||
if expr[2] == "$":
|
||||
# do not append base path
|
||||
path = expr[2:-1]
|
||||
else:
|
||||
path = join(base_dir, expr[2:-1])
|
||||
if subst:
|
||||
path = env.subst(path)
|
||||
out.append(expr[0] + "<" + path + ">")
|
||||
return out
|
||||
|
||||
|
||||
def iter_expressions(expressions: List[str]) -> Generator[Tuple[str, str], None, None]:
|
||||
for expr in expressions:
|
||||
if expr[1:2] != "<" or expr[-1:] != ">":
|
||||
yield ("+", expr)
|
||||
continue
|
||||
yield (expr[0], expr[2:-1])
|
||||
|
||||
|
||||
def apply_options(env: Environment, options: Dict[str, List[str]]):
|
||||
non_expr_keys = ["CPPDEFINES"]
|
||||
for key, values in options.items():
|
||||
if not values:
|
||||
continue
|
||||
if key in non_expr_keys or not isinstance(values[0], str):
|
||||
env.Append(**{key: values})
|
||||
continue
|
||||
for dir, value in iter_expressions(values):
|
||||
if dir == "+":
|
||||
env.Append(**{key: [value]})
|
||||
elif dir == "!":
|
||||
env.Prepend(**{key: [value]})
|
||||
elif dir == "-":
|
||||
if value not in env[key]:
|
||||
raise ValueError(f"Invalid option; {value} is not in {key}")
|
||||
env[key].remove(value)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Library:
|
||||
env: InitVar[Environment]
|
||||
name: str
|
||||
base_dir: str
|
||||
srcs: List[str]
|
||||
includes: List[str] = field(default_factory=lambda: [])
|
||||
options: Dict[str, List[str]] = field(default_factory=lambda: {})
|
||||
|
||||
def __post_init__(self, env: Environment):
|
||||
# add base dir to all globs
|
||||
self.srcs = add_base_dir(env, self.base_dir, self.srcs)
|
||||
self.includes = add_base_dir(env, self.base_dir, self.includes, subst=True)
|
||||
|
||||
|
||||
class LibraryQueue:
|
||||
env: Environment
|
||||
name: str
|
||||
queue: List[Library]
|
||||
includes: List[str]
|
||||
options_public: dict
|
||||
options_private: dict
|
||||
prepend_includes: bool
|
||||
built: bool = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
env: Environment,
|
||||
name: str,
|
||||
prepend_includes: bool = False,
|
||||
) -> None:
|
||||
self.env = env
|
||||
self.name = name
|
||||
self.queue = []
|
||||
self.includes = []
|
||||
self.options_public = {}
|
||||
self.options_private = {}
|
||||
self.prepend_includes = prepend_includes
|
||||
|
||||
def AddLibrary(self, **kwargs):
|
||||
lib = Library(env=self.env, **kwargs)
|
||||
# search all include paths
|
||||
for dir, expr in iter_expressions(lib.includes):
|
||||
if dir == "-":
|
||||
for item in fnmatch.filter(self.includes, expr):
|
||||
if item in self.includes:
|
||||
self.includes.remove(item)
|
||||
continue
|
||||
for item in glob(expr, recursive=True):
|
||||
if not isdir(item):
|
||||
continue
|
||||
if dir == "!":
|
||||
self.includes.insert(0, item)
|
||||
else:
|
||||
self.includes.append(item)
|
||||
self.queue.append(lib)
|
||||
|
||||
def AddExternalLibrary(self, name: str, port: Optional[str] = None):
|
||||
return self.env.AddExternalLibrary(self, name, port)
|
||||
|
||||
def AppendPublic(self, **kwargs):
|
||||
if "CPPPATH" in kwargs:
|
||||
self.includes += kwargs["CPPPATH"]
|
||||
kwargs.pop("CPPPATH")
|
||||
self.options_public = merge_dicts(self.options_public, kwargs)
|
||||
|
||||
def AppendPrivate(self, **kwargs):
|
||||
public_only = ["CPPPATH", "LIBPATH", "LIBS", "LINKFLAGS"]
|
||||
if any(key in public_only for key in kwargs.keys()):
|
||||
raise ValueError("Cannot set these as private options")
|
||||
self.options_private = merge_dicts(self.options_private, kwargs)
|
||||
|
||||
def Print(self):
|
||||
def print_list(items):
|
||||
print(
|
||||
"\n".join(
|
||||
f"{i+1: 4d}. {self.env.subst(str(item))}"
|
||||
for i, item in enumerate(items)
|
||||
)
|
||||
)
|
||||
|
||||
print()
|
||||
print(f"Library Queue - {self.name}")
|
||||
print("Environment paths:")
|
||||
print_list(self.env["CPPPATH"])
|
||||
print(
|
||||
"Include paths (%s):" % ("prepend" if self.prepend_includes else "append")
|
||||
)
|
||||
print_list(self.includes)
|
||||
print("Environment options:")
|
||||
opts = ["CFLAGS", "CCFLAGS", "CXXFLAGS", "CPPDEFINES", "ASFLAGS"]
|
||||
opts = {k: v for k, v in self.env.items() if k in opts}
|
||||
print_list(opts.items())
|
||||
print("Options - public:")
|
||||
print_list(self.options_public.items())
|
||||
print("Options - private:")
|
||||
print_list(self.options_private.items())
|
||||
print("Libraries:")
|
||||
print_list(self.queue)
|
||||
|
||||
def BuildLibraries(self):
|
||||
if self.built:
|
||||
raise RuntimeError("Cannot build a library queue twice")
|
||||
self.Print()
|
||||
|
||||
# add public options to the environment
|
||||
apply_options(self.env, self.options_public)
|
||||
# treat all include paths as public
|
||||
if self.prepend_includes:
|
||||
self.env.Prepend(CPPPATH=self.includes)
|
||||
else:
|
||||
self.env.Append(CPPPATH=self.includes)
|
||||
|
||||
# clone the environment for the whole library queue
|
||||
queue_env = self.env.Clone()
|
||||
# add private options to the cloned environment
|
||||
apply_options(queue_env, self.options_private)
|
||||
|
||||
for lib in self.queue:
|
||||
if lib.options:
|
||||
# clone the environment separately for each library
|
||||
lib_env = queue_env.Clone()
|
||||
# add library-scoped options
|
||||
apply_options(lib_env, lib.options)
|
||||
else:
|
||||
# no library-scoped options, just use the base env
|
||||
lib_env = queue_env
|
||||
# build library with (name, base_dir, sources) options
|
||||
target = lib_env.BuildLibrary(
|
||||
join("$BUILD_DIR", lib.name), lib.base_dir, lib.srcs
|
||||
)
|
||||
self.env.Prepend(LIBS=[target])
|
||||
|
||||
self.built = True
|
||||
|
||||
|
||||
def env_add_library_queue(
|
||||
env: Environment,
|
||||
name: str,
|
||||
prepend_includes: bool = False,
|
||||
) -> LibraryQueue:
|
||||
return LibraryQueue(env, name, prepend_includes)
|
||||
|
||||
|
||||
env.AddMethod(env_add_library_queue, "AddLibraryQueue")
|
||||
@@ -1,115 +0,0 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2022-05-04.
|
||||
|
||||
import fnmatch
|
||||
from glob import glob
|
||||
from os.path import isdir, join
|
||||
from typing import Dict, Generator, List, Tuple
|
||||
|
||||
from SCons.Script import DefaultEnvironment, Environment
|
||||
|
||||
env: Environment = DefaultEnvironment()
|
||||
|
||||
|
||||
def add_base_dir(
|
||||
env: Environment,
|
||||
base_dir: str,
|
||||
expressions: List[str],
|
||||
subst: bool = False,
|
||||
):
|
||||
out = []
|
||||
for expr in expressions:
|
||||
if expr == False:
|
||||
# support '[cond] and [path]' logical expressions
|
||||
continue
|
||||
if expr[1] != "<" or expr[-1] != ">":
|
||||
raise ValueError(f"Not a valid glob: {expr}")
|
||||
if expr[2] == "$":
|
||||
# do not append base path
|
||||
path = expr[2:-1]
|
||||
else:
|
||||
path = join(base_dir, expr[2:-1])
|
||||
if subst:
|
||||
path = env.subst(path)
|
||||
out.append(expr[0] + "<" + path + ">")
|
||||
return out
|
||||
|
||||
|
||||
def iter_expressions(expressions: List[str]) -> Generator[Tuple[str, str], None, None]:
|
||||
for expr in expressions:
|
||||
if expr[1] != "<" or expr[-1] != ">":
|
||||
yield ("+", expr)
|
||||
continue
|
||||
yield (expr[0], expr[2:-1])
|
||||
|
||||
|
||||
def env_add_library(
|
||||
env: Environment,
|
||||
name: str,
|
||||
base_dir: str,
|
||||
srcs: List[str],
|
||||
includes: List[str] = [],
|
||||
options: Dict[str, List[str]] = {},
|
||||
):
|
||||
name = env.subst(name)
|
||||
# add base dir to all globs
|
||||
srcs = add_base_dir(env, base_dir, srcs)
|
||||
includes = add_base_dir(env, base_dir, includes, subst=True)
|
||||
|
||||
# allow removing sources from parent builders
|
||||
key = f"LIB_{name.upper()}_SKIP"
|
||||
if key in env:
|
||||
for expr in env[key]:
|
||||
srcs.append("-<" + expr + ">")
|
||||
|
||||
# queue library for further env clone and build
|
||||
if srcs:
|
||||
env.Prepend(
|
||||
LIBQUEUE=[
|
||||
(join("$BUILD_DIR", name), base_dir, srcs, options),
|
||||
]
|
||||
)
|
||||
|
||||
# search all include paths
|
||||
for dir, expr in iter_expressions(includes):
|
||||
if dir == "-":
|
||||
for item in fnmatch.filter(env["CPPPATH"], expr):
|
||||
if item in env["CPPPATH"]:
|
||||
env["CPPPATH"].remove(item)
|
||||
else:
|
||||
for item in glob(expr, recursive=True):
|
||||
if not isdir(item):
|
||||
continue
|
||||
if dir == "!":
|
||||
env.Prepend(CPPPATH=[item])
|
||||
else:
|
||||
env.Append(CPPPATH=[item])
|
||||
|
||||
|
||||
def env_build_libraries(env: Environment, safe: bool = True):
|
||||
# add lib targets and clone safe envs
|
||||
if not "LIBQUEUE" in env:
|
||||
return
|
||||
queue = env["LIBQUEUE"]
|
||||
env["LIBQUEUE"] = []
|
||||
for lib in queue:
|
||||
envsafe = env.Clone() if safe else env
|
||||
# get env options to add/remove
|
||||
options: Dict[str, List[str]] = lib[3]
|
||||
# change only safe env options
|
||||
for key, values in options.items():
|
||||
for dir, value in iter_expressions(values):
|
||||
if dir == "+":
|
||||
envsafe.Append(**{key: [value]})
|
||||
elif dir == "!":
|
||||
envsafe.Prepend(**{key: [value]})
|
||||
elif dir == "-":
|
||||
if value not in envsafe[key]:
|
||||
raise ValueError(f"Invalid option; {value} is not in {key}")
|
||||
envsafe[key].remove(value)
|
||||
# build library with (name, base_dir, sources) options
|
||||
target = envsafe.BuildLibrary(*lib[0:3])
|
||||
env.Prepend(LIBS=[target])
|
||||
|
||||
|
||||
env.AddMethod(env_add_library, "AddLibrary")
|
||||
env.AddMethod(env_build_libraries, "BuildLibraries")
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <variant.h>
|
||||
|
||||
// Choose the main UART output port
|
||||
#ifndef LT_UART_DEFAULT_PORT
|
||||
#if HAS_SERIAL2
|
||||
|
||||
Reference in New Issue
Block a user