unleashed-firmware/SConstruct
hedger 6b6ea44802
fbt: initial blackmagic support (#1362)
* fbt: added separate script for Windows env setup; moved flash targets from firmware.scons to SConstruct; added Blackmagic support with automatic probe port resolution; added apps.c rebuild on any manifest.fam changes; fixed simultaneous flash & debug ops
* fbt: added networked BlackmagicResolver mode; added `get_blackmagic` target for IDE integration
* fbt: cleanup
* fbt: docs update; fixed blackmagic lookup on certain usb hubs
* fbt: removed explicit python serial port import
* fbt: cleanup
* fbt: raising exception on multiple serial blackmagic probes
2022-07-05 02:53:04 +10:00

215 lines
5.6 KiB
Python

#
# Main Fipper Build System entry point
#
# This file is evaluated by scons (the build system) every time fbt is invoked.
# Scons constructs all referenced environments & their targets' dependency
# trees on startup. So, to keep startup time as low as possible, we're hiding
# construction of certain targets behind command-line options.
import os
DefaultEnvironment(tools=[])
# Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15)
# This environment is created only for loading options & validating file/dir existance
fbt_variables = SConscript("site_scons/commandline.scons")
cmd_environment = Environment(tools=[], variables=fbt_variables)
Help(fbt_variables.GenerateHelpText(cmd_environment))
# Building basic environment - tools, utility methods, cross-compilation
# settings, gcc flags for Cortex-M4, basic builders and more
coreenv = SConscript(
"site_scons/environ.scons",
exports={"VAR_ENV": cmd_environment},
)
SConscript("site_scons/cc.scons", exports={"ENV": coreenv})
# Store root dir in environment for certain tools
coreenv["ROOT_DIR"] = Dir(".")
# Create a separate "dist" environment and add construction envs to it
distenv = coreenv.Clone(
tools=["fbt_dist", "openocd", "blackmagic"],
OPENOCD_GDB_PIPE=["|openocd -c 'gdb_port pipe' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"],
GDBOPTS_BASE=[
"-ex",
"target extended-remote ${GDBREMOTE}",
"-ex",
"set confirm off",
],
GDBOPTS_BLACKMAGIC=[
"-ex",
"monitor swdp_scan",
"-ex",
"monitor debug_bmp enable",
"-ex",
"attach 1",
"-ex",
"set mem inaccessible-by-default off",
],
GDBPYOPTS=[
"-ex",
"source debug/FreeRTOS/FreeRTOS.py",
"-ex",
"source debug/PyCortexMDebug/PyCortexMDebug.py",
"-ex",
"svd_load ${SVD_FILE}",
"-ex",
"compare-sections",
],
ENV=os.environ,
)
firmware_env = distenv.AddFwProject(
base_env=coreenv,
fw_type="firmware",
fw_env_key="FW_ENV",
)
# If enabled, initialize updater-related targets
if GetOption("fullenv"):
updater_env = distenv.AddFwProject(
base_env=coreenv,
fw_type="updater",
fw_env_key="UPD_ENV",
)
# Target for self-update package
dist_arguments = [
"-r",
'"${ROOT_DIR.abspath}/assets/resources"',
"--bundlever",
'"${UPDATE_VERSION_STRING}"',
"--radio",
'"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}"',
"--radiotype",
"${COPRO_STACK_TYPE}",
"${COPRO_DISCLAIMER}",
"--obdata",
'"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"',
]
if distenv["UPDATE_SPLASH"]:
dist_arguments += [
"--splash",
distenv.subst("assets/slideshow/$UPDATE_SPLASH"),
]
selfupdate_dist = distenv.DistCommand(
"updater_package",
(distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]),
DIST_EXTRA=dist_arguments,
)
# Updater debug
distenv.PhonyTarget(
"updater_debug",
"${GDBPYCOM}",
source=updater_env["FW_ELF"],
GDBREMOTE="${OPENOCD_GDB_PIPE}",
)
distenv.PhonyTarget(
"updater_blackmagic",
"${GDBPYCOM}",
source=updater_env["FW_ELF"],
GDBOPTS=distenv.subst("$GDBOPTS_BLACKMAGIC"),
GDBREMOTE="${BLACKMAGIC_ADDR}",
)
# Installation over USB & CLI
usb_update_package = distenv.UsbInstall(
"#build/usbinstall.flag",
(
distenv["DIST_DEPENDS"],
firmware_env["FW_RESOURCES"],
selfupdate_dist,
),
)
if distenv["FORCE"]:
distenv.AlwaysBuild(usb_update_package)
distenv.Depends(usb_update_package, selfupdate_dist)
distenv.Alias("flash_usb", usb_update_package)
# Target for copying & renaming binaries to dist folder
basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"])
distenv.Default(basic_dist)
# Target for bundling core2 package for qFlipper
copro_dist = distenv.CoproBuilder(
distenv.Dir("assets/core2_firmware"),
[],
)
distenv.Alias("copro_dist", copro_dist)
firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env)
distenv.Alias("flash", firmware_flash)
firmware_bm_flash = distenv.PhonyTarget(
"flash_blackmagic",
"$GDB $GDBOPTS $SOURCES $GDBFLASH",
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
GDBREMOTE="${BLACKMAGIC_ADDR}",
GDBFLASH=[
"-ex",
"load",
"-ex",
"quit",
],
)
# Debugging firmware
firmware_debug = distenv.PhonyTarget(
"debug",
"${GDBPYCOM}",
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE}",
GDBREMOTE="${OPENOCD_GDB_PIPE}",
)
distenv.Depends(firmware_debug, firmware_flash)
distenv.PhonyTarget(
"blackmagic",
"${GDBPYCOM}",
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
GDBREMOTE="${BLACKMAGIC_ADDR}",
)
# Debug alien elf
distenv.PhonyTarget(
"debug_other",
"${GDBPYCOM}",
GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ',
GDBREMOTE="${OPENOCD_GDB_PIPE}",
)
# Just start OpenOCD
distenv.PhonyTarget(
"openocd",
"${OPENOCDCOM}",
)
# Linter
distenv.PhonyTarget(
"lint",
"${PYTHON3} scripts/lint.py check ${LINT_SOURCES}",
LINT_SOURCES=firmware_env["LINT_SOURCES"],
)
distenv.PhonyTarget(
"format",
"${PYTHON3} scripts/lint.py format ${LINT_SOURCES}",
LINT_SOURCES=firmware_env["LINT_SOURCES"],
)
# Find blackmagic probe
distenv.PhonyTarget(
"get_blackmagic",
"@echo $( ${BLACKMAGIC_ADDR} $)",
)