2022-06-26 12:00:03 +00:00
|
|
|
#
|
2022-08-30 12:15:14 +00:00
|
|
|
# Main Flipper Build System entry point
|
2022-06-26 12:00:03 +00:00
|
|
|
#
|
|
|
|
# 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
|
2022-11-10 11:55:11 +00:00
|
|
|
from fbt.util import path_as_posix
|
2022-06-26 12:00:03 +00:00
|
|
|
|
2022-09-14 16:11:38 +00:00
|
|
|
DefaultEnvironment(tools=[])
|
|
|
|
|
2022-07-14 16:24:26 +00:00
|
|
|
EnsurePythonVersion(3, 8)
|
|
|
|
|
2022-06-26 12:00:03 +00:00
|
|
|
# Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15)
|
|
|
|
|
2022-08-30 12:15:14 +00:00
|
|
|
# This environment is created only for loading options & validating file/dir existence
|
2022-06-26 12:00:03 +00:00
|
|
|
fbt_variables = SConscript("site_scons/commandline.scons")
|
2022-10-12 16:12:05 +00:00
|
|
|
cmd_environment = Environment(
|
|
|
|
toolpath=["#/scripts/fbt_tools"],
|
|
|
|
tools=[
|
|
|
|
("fbt_help", {"vars": fbt_variables}),
|
|
|
|
],
|
|
|
|
variables=fbt_variables,
|
|
|
|
)
|
2022-06-26 12:00:03 +00:00
|
|
|
|
|
|
|
# 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},
|
2022-10-12 16:12:05 +00:00
|
|
|
toolpath=["#/scripts/fbt_tools"],
|
2022-06-26 12:00:03 +00:00
|
|
|
)
|
|
|
|
SConscript("site_scons/cc.scons", exports={"ENV": coreenv})
|
|
|
|
|
|
|
|
# Create a separate "dist" environment and add construction envs to it
|
|
|
|
distenv = coreenv.Clone(
|
2022-10-12 16:12:05 +00:00
|
|
|
tools=[
|
|
|
|
"fbt_dist",
|
|
|
|
"fbt_debugopts",
|
|
|
|
"openocd",
|
|
|
|
"blackmagic",
|
|
|
|
"jflash",
|
2022-07-04 16:53:04 +00:00
|
|
|
],
|
2022-06-26 12:00:03 +00:00
|
|
|
ENV=os.environ,
|
2022-11-05 11:47:59 +00:00
|
|
|
UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}",
|
2022-06-26 12:00:03 +00:00
|
|
|
)
|
|
|
|
|
2022-07-04 16:53:04 +00:00
|
|
|
firmware_env = distenv.AddFwProject(
|
2022-06-26 12:00:03 +00:00
|
|
|
base_env=coreenv,
|
|
|
|
fw_type="firmware",
|
|
|
|
fw_env_key="FW_ENV",
|
|
|
|
)
|
|
|
|
|
|
|
|
# If enabled, initialize updater-related targets
|
2022-08-02 13:46:43 +00:00
|
|
|
if GetOption("fullenv") or any(
|
|
|
|
filter(lambda target: "updater" in target or "flash_usb" in target, BUILD_TARGETS)
|
|
|
|
):
|
2022-07-04 16:53:04 +00:00
|
|
|
updater_env = distenv.AddFwProject(
|
2022-06-26 12:00:03 +00:00
|
|
|
base_env=coreenv,
|
|
|
|
fw_type="updater",
|
|
|
|
fw_env_key="UPD_ENV",
|
|
|
|
)
|
|
|
|
|
|
|
|
# Target for self-update package
|
2022-08-02 13:46:43 +00:00
|
|
|
dist_basic_arguments = [
|
2022-06-26 12:00:03 +00:00
|
|
|
"--bundlever",
|
|
|
|
'"${UPDATE_VERSION_STRING}"',
|
2022-08-02 13:46:43 +00:00
|
|
|
]
|
|
|
|
dist_radio_arguments = [
|
2022-06-26 12:00:03 +00:00
|
|
|
"--radio",
|
|
|
|
'"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}"',
|
|
|
|
"--radiotype",
|
|
|
|
"${COPRO_STACK_TYPE}",
|
|
|
|
"${COPRO_DISCLAIMER}",
|
|
|
|
"--obdata",
|
|
|
|
'"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"',
|
|
|
|
]
|
2022-08-02 13:46:43 +00:00
|
|
|
dist_resource_arguments = [
|
|
|
|
"-r",
|
|
|
|
'"${ROOT_DIR.abspath}/assets/resources"',
|
|
|
|
]
|
|
|
|
dist_splash_arguments = (
|
|
|
|
[
|
2022-06-26 12:00:03 +00:00
|
|
|
"--splash",
|
|
|
|
distenv.subst("assets/slideshow/$UPDATE_SPLASH"),
|
|
|
|
]
|
2022-08-02 13:46:43 +00:00
|
|
|
if distenv["UPDATE_SPLASH"]
|
|
|
|
else []
|
|
|
|
)
|
2022-06-30 16:06:12 +00:00
|
|
|
|
|
|
|
selfupdate_dist = distenv.DistCommand(
|
|
|
|
"updater_package",
|
2022-07-04 16:53:04 +00:00
|
|
|
(distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]),
|
2022-08-02 13:46:43 +00:00
|
|
|
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,
|
2022-06-26 12:00:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
# Updater debug
|
2022-07-04 16:53:04 +00:00
|
|
|
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}",
|
|
|
|
)
|
2022-06-26 12:00:03 +00:00
|
|
|
|
2022-06-28 13:03:49 +00:00
|
|
|
# Installation over USB & CLI
|
2022-08-02 13:46:43 +00:00
|
|
|
usb_update_package = distenv.AddUsbFlashTarget(
|
|
|
|
"#build/usbinstall.flag", (firmware_env["FW_RESOURCES"], selfupdate_dist)
|
2022-06-28 13:03:49 +00:00
|
|
|
)
|
2022-08-02 13:46:43 +00:00
|
|
|
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)
|
|
|
|
|
2022-06-26 12:00:03 +00:00
|
|
|
|
|
|
|
# Target for copying & renaming binaries to dist folder
|
2022-06-30 16:06:12 +00:00
|
|
|
basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"])
|
|
|
|
distenv.Default(basic_dist)
|
2022-06-28 13:03:49 +00:00
|
|
|
|
2023-03-14 16:55:16 +00:00
|
|
|
dist_dir_name = distenv.GetProjectDirName()
|
2023-03-14 14:29:28 +00:00
|
|
|
dist_dir = distenv.Dir(f"#/dist/{dist_dir_name}")
|
|
|
|
external_apps_artifacts = firmware_env["FW_EXTAPPS"]
|
|
|
|
external_app_list = external_apps_artifacts.application_map.values()
|
|
|
|
|
2022-10-12 16:12:05 +00:00
|
|
|
fap_dist = [
|
2022-09-14 16:11:38 +00:00
|
|
|
distenv.Install(
|
2023-03-14 14:29:28 +00:00
|
|
|
dist_dir.Dir("debug_elf"),
|
|
|
|
list(app_artifact.debug for app_artifact in external_app_list),
|
2022-09-14 16:11:38 +00:00
|
|
|
),
|
2023-01-17 15:07:47 +00:00
|
|
|
*(
|
|
|
|
distenv.Install(
|
2023-03-14 14:29:28 +00:00
|
|
|
dist_dir.File(dist_entry[1]).dir,
|
|
|
|
app_artifact.compact,
|
2023-01-17 15:07:47 +00:00
|
|
|
)
|
2023-03-14 14:29:28 +00:00
|
|
|
for app_artifact in external_app_list
|
|
|
|
for dist_entry in app_artifact.dist_entries
|
2022-09-14 16:11:38 +00:00
|
|
|
),
|
|
|
|
]
|
2022-11-05 11:47:59 +00:00
|
|
|
Depends(
|
|
|
|
fap_dist,
|
2023-03-14 14:29:28 +00:00
|
|
|
list(app_artifact.validator for app_artifact in external_app_list),
|
2022-11-05 11:47:59 +00:00
|
|
|
)
|
2022-10-12 16:12:05 +00:00
|
|
|
Alias("fap_dist", fap_dist)
|
|
|
|
# distenv.Default(fap_dist)
|
2022-09-14 16:11:38 +00:00
|
|
|
|
2023-03-14 14:29:28 +00:00
|
|
|
distenv.Depends(firmware_env["FW_RESOURCES"], external_apps_artifacts.resources_dist)
|
2022-09-14 16:11:38 +00:00
|
|
|
|
2023-01-11 10:13:07 +00:00
|
|
|
# Copy all faps to device
|
|
|
|
|
|
|
|
fap_deploy = distenv.PhonyTarget(
|
|
|
|
"fap_deploy",
|
|
|
|
"${PYTHON3} ${ROOT_DIR}/scripts/storage.py send ${SOURCE} /ext/apps",
|
|
|
|
source=Dir("#/assets/resources/apps"),
|
|
|
|
)
|
|
|
|
|
2022-09-14 16:11:38 +00:00
|
|
|
|
2022-06-26 12:00:03 +00:00
|
|
|
# Target for bundling core2 package for qFlipper
|
|
|
|
copro_dist = distenv.CoproBuilder(
|
2022-10-12 16:12:05 +00:00
|
|
|
"#/build/core2_firmware.tgz",
|
2022-06-26 12:00:03 +00:00
|
|
|
[],
|
|
|
|
)
|
2022-10-12 16:12:05 +00:00
|
|
|
distenv.AlwaysBuild(copro_dist)
|
2022-06-30 16:06:12 +00:00
|
|
|
distenv.Alias("copro_dist", copro_dist)
|
2022-06-26 12:00:03 +00:00
|
|
|
|
2022-07-04 16:53:04 +00:00
|
|
|
firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env)
|
|
|
|
distenv.Alias("flash", firmware_flash)
|
2022-08-02 13:46:43 +00:00
|
|
|
|
|
|
|
firmware_jflash = distenv.AddJFlashTarget(firmware_env)
|
|
|
|
distenv.Alias("jflash", firmware_jflash)
|
2022-07-04 16:53:04 +00:00
|
|
|
|
|
|
|
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",
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
Splitting units and updater benches (#2165)
* test run, moved updated to separate physical runner/flipper/card
* simplified units, removed re-flashing, moved format to beginning of run
* added reboot requence and mini optimizations
* forgot gitadd, added script modifications, workflow changes
* fixed linter issues
* moved updater to unit bench for speed up
* changes to units, flash (not full) on second update, new fbt GDB thread check
* changed serial of second device
* testing pipelines, added failing unit test
* fixed gdb step
* fixed gdb step v2 electric boogaloo
* fixed gdb step v3, fixed target
* reverted while1 in units, tests complete
* testing colored output
* trying different term setting
* debug outputs for terminal
* fixed typo in SConstruct and another terminal test
* reverted changes, no colored output, for production
* fixed log output to readable format
* fixed linter
Co-authored-by: Konstantin Volkov <k.volkov@flipperdevices.com>
Co-authored-by: あく <alleteam@gmail.com>
2022-12-28 14:16:06 +00:00
|
|
|
gdb_backtrace_all_threads = distenv.PhonyTarget(
|
|
|
|
"gdb_trace_all",
|
|
|
|
"$GDB $GDBOPTS $SOURCES $GDBFLASH",
|
|
|
|
source=firmware_env["FW_ELF"],
|
|
|
|
GDBOPTS="${GDBOPTS_BASE}",
|
|
|
|
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
|
|
|
GDBFLASH=[
|
|
|
|
"-ex",
|
|
|
|
"thread apply all bt",
|
|
|
|
"-ex",
|
|
|
|
"quit",
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
2022-06-26 12:00:03 +00:00
|
|
|
# Debugging firmware
|
2022-07-04 16:53:04 +00:00
|
|
|
firmware_debug = distenv.PhonyTarget(
|
|
|
|
"debug",
|
|
|
|
"${GDBPYCOM}",
|
|
|
|
source=firmware_env["FW_ELF"],
|
|
|
|
GDBOPTS="${GDBOPTS_BASE}",
|
|
|
|
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
2022-11-10 11:55:11 +00:00
|
|
|
FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")),
|
2022-07-04 16:53:04 +00:00
|
|
|
)
|
|
|
|
distenv.Depends(firmware_debug, firmware_flash)
|
|
|
|
|
|
|
|
distenv.PhonyTarget(
|
|
|
|
"blackmagic",
|
|
|
|
"${GDBPYCOM}",
|
|
|
|
source=firmware_env["FW_ELF"],
|
|
|
|
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
|
|
|
|
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
2022-11-10 11:55:11 +00:00
|
|
|
FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")),
|
2022-07-04 16:53:04 +00:00
|
|
|
)
|
|
|
|
|
2022-06-26 12:00:03 +00:00
|
|
|
# Debug alien elf
|
2022-06-30 16:06:12 +00:00
|
|
|
distenv.PhonyTarget(
|
|
|
|
"debug_other",
|
2022-07-04 16:53:04 +00:00
|
|
|
"${GDBPYCOM}",
|
2022-09-21 14:42:59 +00:00
|
|
|
GDBOPTS="${GDBOPTS_BASE}",
|
2022-07-04 16:53:04 +00:00
|
|
|
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
2022-11-05 11:47:59 +00:00
|
|
|
GDBPYOPTS='-ex "source ${FBT_DEBUG_DIR}/PyCortexMDebug/PyCortexMDebug.py" ',
|
2022-06-26 12:00:03 +00:00
|
|
|
)
|
|
|
|
|
2022-09-21 14:42:59 +00:00
|
|
|
distenv.PhonyTarget(
|
|
|
|
"debug_other_blackmagic",
|
|
|
|
"${GDBPYCOM}",
|
|
|
|
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
|
|
|
|
GDBREMOTE="$${BLACKMAGIC_ADDR}",
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-06-26 12:00:03 +00:00
|
|
|
# Just start OpenOCD
|
2022-06-30 16:06:12 +00:00
|
|
|
distenv.PhonyTarget(
|
|
|
|
"openocd",
|
|
|
|
"${OPENOCDCOM}",
|
|
|
|
)
|
2022-06-26 12:00:03 +00:00
|
|
|
|
|
|
|
# Linter
|
2022-06-30 16:06:12 +00:00
|
|
|
distenv.PhonyTarget(
|
|
|
|
"lint",
|
2022-11-02 15:15:40 +00:00
|
|
|
"${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}",
|
2022-11-12 10:03:22 +00:00
|
|
|
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
|
2022-06-26 12:00:03 +00:00
|
|
|
)
|
|
|
|
|
2022-06-30 16:06:12 +00:00
|
|
|
distenv.PhonyTarget(
|
|
|
|
"format",
|
2022-11-02 15:15:40 +00:00
|
|
|
"${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}",
|
2022-11-12 10:03:22 +00:00
|
|
|
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
|
2022-07-04 16:53:04 +00:00
|
|
|
)
|
|
|
|
|
2022-08-02 14:05:31 +00:00
|
|
|
# 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
|
2022-11-02 15:15:40 +00:00
|
|
|
distenv.PhonyTarget("cli", "${PYTHON3} ${FBT_SCRIPT_DIR}/serial_cli.py")
|
2022-08-02 14:05:31 +00:00
|
|
|
|
2022-07-04 16:53:04 +00:00
|
|
|
|
|
|
|
# Find blackmagic probe
|
|
|
|
distenv.PhonyTarget(
|
|
|
|
"get_blackmagic",
|
|
|
|
"@echo $( ${BLACKMAGIC_ADDR} $)",
|
2022-06-26 12:00:03 +00:00
|
|
|
)
|
2022-08-03 16:32:31 +00:00
|
|
|
|
2022-10-25 22:15:02 +00:00
|
|
|
|
|
|
|
# Find STLink probe ids
|
|
|
|
distenv.PhonyTarget(
|
|
|
|
"get_stlink",
|
|
|
|
distenv.Action(
|
|
|
|
lambda **kw: distenv.GetDevices(),
|
|
|
|
None,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
2022-08-03 16:32:31 +00:00
|
|
|
# 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)
|