| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- #
- # Main Flipper 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=[])
- EnsurePythonVersion(3, 8)
- # Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15)
- # This environment is created only for loading options & validating file/dir existence
- fbt_variables = SConscript("site_scons/commandline.scons")
- cmd_environment = Environment(
- toolpath=["#/scripts/fbt_tools"],
- tools=[
- ("fbt_help", {"vars": fbt_variables}),
- ],
- variables=fbt_variables,
- )
- # 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},
- toolpath=["#/scripts/fbt_tools"],
- )
- SConscript("site_scons/cc.scons", exports={"ENV": coreenv})
- # Create a separate "dist" environment and add construction envs to it
- distenv = coreenv.Clone(
- tools=[
- "fbt_dist",
- "fbt_debugopts",
- "openocd",
- "blackmagic",
- "jflash",
- ],
- ENV=os.environ,
- UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}",
- )
- firmware_env = distenv.AddFwProject(
- base_env=coreenv,
- fw_type="firmware",
- fw_env_key="FW_ENV",
- )
- # If enabled, initialize updater-related targets
- if GetOption("fullenv") or any(
- filter(lambda target: "updater" in target or "flash_usb" in target, BUILD_TARGETS)
- ):
- updater_env = distenv.AddFwProject(
- base_env=coreenv,
- fw_type="updater",
- fw_env_key="UPD_ENV",
- )
- # Target for self-update package
- dist_basic_arguments = [
- "--bundlever",
- '"${UPDATE_VERSION_STRING}"',
- ]
- dist_radio_arguments = [
- "--radio",
- '"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}"',
- "--radiotype",
- "${COPRO_STACK_TYPE}",
- "${COPRO_DISCLAIMER}",
- "--obdata",
- '"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"',
- ]
- dist_resource_arguments = [
- "-r",
- '"${ROOT_DIR.abspath}/assets/resources"',
- ]
- dist_splash_arguments = (
- [
- "--splash",
- distenv.subst("assets/slideshow/$UPDATE_SPLASH"),
- ]
- if distenv["UPDATE_SPLASH"]
- else []
- )
- selfupdate_dist = distenv.DistCommand(
- "updater_package",
- (distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]),
- DIST_EXTRA=[
- *dist_basic_arguments,
- *dist_radio_arguments,
- *dist_resource_arguments,
- *dist_splash_arguments,
- ],
- )
- selfupdate_min_dist = distenv.DistCommand(
- "updater_minpackage",
- distenv["DIST_DEPENDS"],
- DIST_EXTRA=dist_basic_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.AddUsbFlashTarget(
- "#build/usbinstall.flag", (firmware_env["FW_RESOURCES"], selfupdate_dist)
- )
- distenv.Alias("flash_usb_full", usb_update_package)
- usb_minupdate_package = distenv.AddUsbFlashTarget(
- "#build/minusbinstall.flag", (selfupdate_min_dist,)
- )
- distenv.Alias("flash_usb", usb_minupdate_package)
- # Target for copying & renaming binaries to dist folder
- basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"])
- distenv.Default(basic_dist)
- dist_dir = distenv.GetProjetDirName()
- fap_dist = [
- distenv.Install(
- distenv.Dir(f"#/dist/{dist_dir}/apps/debug_elf"),
- list(
- app_artifact.debug
- for app_artifact in firmware_env["FW_EXTAPPS"].applications.values()
- ),
- ),
- distenv.Install(
- f"#/dist/{dist_dir}/apps",
- "#/assets/resources/apps",
- ),
- ]
- Depends(
- fap_dist,
- list(
- app_artifact.validator
- for app_artifact in firmware_env["FW_EXTAPPS"].applications.values()
- ),
- )
- Alias("fap_dist", fap_dist)
- # distenv.Default(fap_dist)
- distenv.Depends(firmware_env["FW_RESOURCES"], firmware_env["FW_EXTAPPS"].resources_dist)
- # Target for bundling core2 package for qFlipper
- copro_dist = distenv.CoproBuilder(
- "#/build/core2_firmware.tgz",
- [],
- )
- distenv.AlwaysBuild(copro_dist)
- distenv.Alias("copro_dist", copro_dist)
- firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env)
- distenv.Alias("flash", firmware_flash)
- firmware_jflash = distenv.AddJFlashTarget(firmware_env)
- distenv.Alias("jflash", firmware_jflash)
- 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}",
- FBT_FAP_DEBUG_ELF_ROOT=firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT").replace(
- "\\", "/"
- ),
- )
- distenv.Depends(firmware_debug, firmware_flash)
- distenv.PhonyTarget(
- "blackmagic",
- "${GDBPYCOM}",
- source=firmware_env["FW_ELF"],
- GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
- GDBREMOTE="${BLACKMAGIC_ADDR}",
- FBT_FAP_DEBUG_ELF_ROOT=firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT").replace(
- "\\", "/"
- ),
- )
- # Debug alien elf
- distenv.PhonyTarget(
- "debug_other",
- "${GDBPYCOM}",
- GDBOPTS="${GDBOPTS_BASE}",
- GDBREMOTE="${OPENOCD_GDB_PIPE}",
- GDBPYOPTS='-ex "source ${FBT_DEBUG_DIR}/PyCortexMDebug/PyCortexMDebug.py" ',
- )
- distenv.PhonyTarget(
- "debug_other_blackmagic",
- "${GDBPYCOM}",
- GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
- GDBREMOTE="$${BLACKMAGIC_ADDR}",
- )
- # Just start OpenOCD
- distenv.PhonyTarget(
- "openocd",
- "${OPENOCDCOM}",
- )
- # Linter
- distenv.PhonyTarget(
- "lint",
- "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}",
- LINT_SOURCES=firmware_env["LINT_SOURCES"],
- )
- distenv.PhonyTarget(
- "format",
- "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}",
- LINT_SOURCES=firmware_env["LINT_SOURCES"],
- )
- # PY_LINT_SOURCES contains recursively-built modules' SConscript files + application manifests
- # Here we add additional Python files residing in repo root
- firmware_env.Append(
- PY_LINT_SOURCES=[
- # Py code folders
- "site_scons",
- "scripts",
- # Extra files
- "SConstruct",
- "firmware.scons",
- "fbt_options.py",
- ]
- )
- black_commandline = "@${PYTHON3} -m black ${PY_BLACK_ARGS} ${PY_LINT_SOURCES}"
- black_base_args = ["--include", '"\\.scons|\\.py|SConscript|SConstruct"']
- distenv.PhonyTarget(
- "lint_py",
- black_commandline,
- PY_BLACK_ARGS=[
- "--check",
- "--diff",
- *black_base_args,
- ],
- PY_LINT_SOURCES=firmware_env["PY_LINT_SOURCES"],
- )
- distenv.PhonyTarget(
- "format_py",
- black_commandline,
- PY_BLACK_ARGS=black_base_args,
- PY_LINT_SOURCES=firmware_env["PY_LINT_SOURCES"],
- )
- # Start Flipper CLI via PySerial's miniterm
- distenv.PhonyTarget("cli", "${PYTHON3} ${FBT_SCRIPT_DIR}/serial_cli.py")
- # Find blackmagic probe
- distenv.PhonyTarget(
- "get_blackmagic",
- "@echo $( ${BLACKMAGIC_ADDR} $)",
- )
- # Find STLink probe ids
- distenv.PhonyTarget(
- "get_stlink",
- distenv.Action(
- lambda **kw: distenv.GetDevices(),
- None,
- ),
- )
- # Prepare vscode environment
- vscode_dist = distenv.Install("#.vscode", distenv.Glob("#.vscode/example/*"))
- distenv.Precious(vscode_dist)
- distenv.NoClean(vscode_dist)
- distenv.Alias("vscode_dist", vscode_dist)
|