fbt: fixes for ufbt pt3 (#1970)
* fbt: replaced debug dir paths with FBT_DEBUG_DIR * scripts: updated requirements.txt * fbt: fixed wrong import * fbt: removed delayed import for file2image * fbt: added UPDATE_BUNDLE_DIR internal var * fbt: cleaner internal management of extapps * applications: added fap_libs for core apps to link with resources when building with --extra-ext-apps * fbt: removed deprecation stub for faps * fbt: added quotation for icons build cmd * fbt: reworked BUILD_DIR & fap work dir handling; fap debug: using debug elf path from fbt * fbt: explicit LIB_DIST_DIR
This commit is contained in:
@@ -139,7 +139,7 @@ def generate(env):
|
||||
BUILDERS={
|
||||
"IconBuilder": Builder(
|
||||
action=Action(
|
||||
'${PYTHON3} "${ASSETS_COMPILER}" icons ${ABSPATHGETTERFUNC(SOURCE)} ${TARGET.dir} --filename ${ICON_FILE_NAME}',
|
||||
'${PYTHON3} "${ASSETS_COMPILER}" icons "${ABSPATHGETTERFUNC(SOURCE)}" "${TARGET.dir}" --filename ${ICON_FILE_NAME}',
|
||||
"${ICONSCOMSTR}",
|
||||
),
|
||||
emitter=icons_emitter,
|
||||
|
@@ -1,7 +1,6 @@
|
||||
from re import search
|
||||
|
||||
from SCons.Errors import UserError
|
||||
from fbt_options import OPENOCD_OPTS
|
||||
|
||||
|
||||
def _get_device_serials(search_str="STLink"):
|
||||
@@ -20,6 +19,9 @@ def GetDevices(env):
|
||||
|
||||
def generate(env, **kw):
|
||||
env.AddMethod(GetDevices)
|
||||
env.SetDefault(
|
||||
FBT_DEBUG_DIR="${ROOT_DIR}/debug",
|
||||
)
|
||||
|
||||
if (adapter_serial := env.subst("$OPENOCD_ADAPTER_SERIAL")) != "auto":
|
||||
env.Append(
|
||||
@@ -36,7 +38,7 @@ def generate(env, **kw):
|
||||
|
||||
env.SetDefault(
|
||||
OPENOCD_GDB_PIPE=[
|
||||
"|openocd -c 'gdb_port pipe; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"
|
||||
"|openocd -c 'gdb_port pipe; log_output ${FBT_DEBUG_DIR}/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"
|
||||
],
|
||||
GDBOPTS_BASE=[
|
||||
"-ex",
|
||||
@@ -58,17 +60,19 @@ def generate(env, **kw):
|
||||
],
|
||||
GDBPYOPTS=[
|
||||
"-ex",
|
||||
"source debug/FreeRTOS/FreeRTOS.py",
|
||||
"source ${FBT_DEBUG_DIR}/FreeRTOS/FreeRTOS.py",
|
||||
"-ex",
|
||||
"source debug/flipperapps.py",
|
||||
"source ${FBT_DEBUG_DIR}/flipperapps.py",
|
||||
"-ex",
|
||||
"source debug/PyCortexMDebug/PyCortexMDebug.py",
|
||||
"fap-set-debug-elf-root ${FBT_FAP_DEBUG_ELF_ROOT}",
|
||||
"-ex",
|
||||
"source ${FBT_DEBUG_DIR}/PyCortexMDebug/PyCortexMDebug.py",
|
||||
"-ex",
|
||||
"svd_load ${SVD_FILE}",
|
||||
"-ex",
|
||||
"compare-sections",
|
||||
],
|
||||
JFLASHPROJECT="${ROOT_DIR.abspath}/debug/fw.jflash",
|
||||
JFLASHPROJECT="${FBT_DEBUG_DIR}/fw.jflash",
|
||||
)
|
||||
|
||||
|
||||
|
@@ -22,7 +22,7 @@ def GetProjetDirName(env, project=None):
|
||||
|
||||
def create_fw_build_targets(env, configuration_name):
|
||||
flavor = GetProjetDirName(env, configuration_name)
|
||||
build_dir = env.Dir("build").Dir(flavor).abspath
|
||||
build_dir = env.Dir("build").Dir(flavor)
|
||||
return env.SConscript(
|
||||
"firmware.scons",
|
||||
variant_dir=build_dir,
|
||||
@@ -131,7 +131,7 @@ def generate(env):
|
||||
"UsbInstall": Builder(
|
||||
action=[
|
||||
Action(
|
||||
'${PYTHON3} "${SELFUPDATE_SCRIPT}" dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}/update.fuf'
|
||||
'${PYTHON3} "${SELFUPDATE_SCRIPT}" ${UPDATE_BUNDLE_DIR}/update.fuf'
|
||||
),
|
||||
Touch("${TARGET}"),
|
||||
]
|
||||
|
@@ -1,6 +1,9 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Optional
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Errors import UserError
|
||||
from SCons.Node import NodeList
|
||||
import SCons.Warnings
|
||||
|
||||
from fbt.elfmanifest import assemble_manifest_data
|
||||
@@ -16,6 +19,15 @@ import shutil
|
||||
from ansi.color import fg
|
||||
|
||||
|
||||
@dataclass
|
||||
class FlipperExternalAppInfo:
|
||||
app: FlipperApplication
|
||||
compact: NodeList = field(default_factory=NodeList)
|
||||
debug: NodeList = field(default_factory=NodeList)
|
||||
validator: NodeList = field(default_factory=NodeList)
|
||||
installer: NodeList = field(default_factory=NodeList)
|
||||
|
||||
|
||||
def BuildAppElf(env, app):
|
||||
ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR")
|
||||
app_work_dir = os.path.join(ext_apps_work_dir, app.appid)
|
||||
@@ -26,15 +38,7 @@ def BuildAppElf(env, app):
|
||||
|
||||
app_alias = f"fap_{app.appid}"
|
||||
|
||||
# Deprecation stub
|
||||
legacy_app_taget_name = f"{app_env['FIRMWARE_BUILD_CFG']}_{app.appid}"
|
||||
|
||||
def legacy_app_build_stub(**kw):
|
||||
raise UserError(
|
||||
f"Target name '{legacy_app_taget_name}' is deprecated, use '{app_alias}' instead"
|
||||
)
|
||||
|
||||
app_env.PhonyTarget(legacy_app_taget_name, Action(legacy_app_build_stub, None))
|
||||
app_artifacts = FlipperExternalAppInfo(app)
|
||||
|
||||
externally_built_files = []
|
||||
if app.fap_extbuild:
|
||||
@@ -115,20 +119,22 @@ def BuildAppElf(env, app):
|
||||
CPPPATH=env.Dir(app_work_dir),
|
||||
)
|
||||
|
||||
app_elf_raw = app_env.Program(
|
||||
app_artifacts.debug = app_env.Program(
|
||||
os.path.join(ext_apps_work_dir, f"{app.appid}_d"),
|
||||
app_sources,
|
||||
APP_ENTRY=app.entry_point,
|
||||
)
|
||||
|
||||
app_env.Clean(app_elf_raw, [*externally_built_files, app_env.Dir(app_work_dir)])
|
||||
app_env.Clean(
|
||||
app_artifacts.debug, [*externally_built_files, app_env.Dir(app_work_dir)]
|
||||
)
|
||||
|
||||
app_elf_dump = app_env.ObjDump(app_elf_raw)
|
||||
app_elf_dump = app_env.ObjDump(app_artifacts.debug)
|
||||
app_env.Alias(f"{app_alias}_list", app_elf_dump)
|
||||
|
||||
app_elf_augmented = app_env.EmbedAppMetadata(
|
||||
app_artifacts.compact = app_env.EmbedAppMetadata(
|
||||
os.path.join(ext_apps_work_dir, app.appid),
|
||||
app_elf_raw,
|
||||
app_artifacts.debug,
|
||||
APP=app,
|
||||
)
|
||||
|
||||
@@ -139,19 +145,21 @@ def BuildAppElf(env, app):
|
||||
}
|
||||
|
||||
app_env.Depends(
|
||||
app_elf_augmented,
|
||||
app_artifacts.compact,
|
||||
[app_env["SDK_DEFINITION"], app_env.Value(manifest_vals)],
|
||||
)
|
||||
if app.fap_icon:
|
||||
app_env.Depends(
|
||||
app_elf_augmented,
|
||||
app_artifacts.compact,
|
||||
app_env.File(f"{app._apppath}/{app.fap_icon}"),
|
||||
)
|
||||
|
||||
app_elf_import_validator = app_env.ValidateAppImports(app_elf_augmented)
|
||||
app_env.AlwaysBuild(app_elf_import_validator)
|
||||
app_env.Alias(app_alias, app_elf_import_validator)
|
||||
return (app_elf_augmented, app_elf_raw, app_elf_import_validator)
|
||||
app_artifacts.validator = app_env.ValidateAppImports(app_artifacts.compact)
|
||||
app_env.AlwaysBuild(app_artifacts.validator)
|
||||
app_env.Alias(app_alias, app_artifacts.validator)
|
||||
|
||||
env["EXT_APPS"][app.appid] = app_artifacts
|
||||
return app_artifacts
|
||||
|
||||
|
||||
def prepare_app_metadata(target, source, env):
|
||||
@@ -182,11 +190,17 @@ def validate_app_imports(target, source, env):
|
||||
app_syms.add(line.split()[0])
|
||||
unresolved_syms = app_syms - sdk_cache.get_valid_names()
|
||||
if unresolved_syms:
|
||||
SCons.Warnings.warn(
|
||||
SCons.Warnings.LinkWarning,
|
||||
fg.brightyellow(f"{source[0].path}: app won't run. Unresolved symbols: ")
|
||||
+ fg.brightmagenta(f"{unresolved_syms}"),
|
||||
)
|
||||
warning_msg = fg.brightyellow(
|
||||
f"{source[0].path}: app won't run. Unresolved symbols: "
|
||||
) + fg.brightmagenta(f"{unresolved_syms}")
|
||||
disabled_api_syms = unresolved_syms.intersection(sdk_cache.get_disabled_names())
|
||||
if disabled_api_syms:
|
||||
warning_msg += (
|
||||
fg.brightyellow(" (in API, but disabled: ")
|
||||
+ fg.brightmagenta(f"{disabled_api_syms}")
|
||||
+ fg.brightyellow(")")
|
||||
)
|
||||
SCons.Warnings.warn(SCons.Warnings.LinkWarning, warning_msg),
|
||||
|
||||
|
||||
def GetExtAppFromPath(env, app_dir):
|
||||
@@ -208,26 +222,26 @@ def GetExtAppFromPath(env, app_dir):
|
||||
if not app:
|
||||
raise UserError(f"Failed to resolve application for given APPSRC={app_dir}")
|
||||
|
||||
app_elf = env["_extapps"]["compact"].get(app.appid, None)
|
||||
if not app_elf:
|
||||
app_artifacts = env["EXT_APPS"].get(app.appid, None)
|
||||
if not app_artifacts:
|
||||
raise UserError(
|
||||
f"Application {app.appid} is not configured for building as external"
|
||||
)
|
||||
|
||||
app_validator = env["_extapps"]["validators"].get(app.appid, None)
|
||||
|
||||
return (app, app_elf[0], app_validator[0])
|
||||
return app_artifacts
|
||||
|
||||
|
||||
def fap_dist_emitter(target, source, env):
|
||||
target_dir = target[0]
|
||||
|
||||
target = []
|
||||
for dist_entry in env["_extapps"]["dist"].values():
|
||||
target.append(target_dir.Dir(dist_entry[0]).File(dist_entry[1][0].name))
|
||||
|
||||
for compact_entry in env["_extapps"]["compact"].values():
|
||||
source.extend(compact_entry)
|
||||
for _, app_artifacts in env["EXT_APPS"].items():
|
||||
source.extend(app_artifacts.compact)
|
||||
target.append(
|
||||
target_dir.Dir(app_artifacts.app.fap_category).File(
|
||||
app_artifacts.compact[0].name
|
||||
)
|
||||
)
|
||||
|
||||
return (target, source)
|
||||
|
||||
@@ -244,10 +258,9 @@ def fap_dist_action(target, source, env):
|
||||
|
||||
def generate(env, **kw):
|
||||
env.SetDefault(
|
||||
EXT_APPS_WORK_DIR=kw.get("EXT_APPS_WORK_DIR"),
|
||||
EXT_APPS_WORK_DIR="${FBT_FAP_DEBUG_ELF_ROOT}",
|
||||
APP_RUN_SCRIPT="${FBT_SCRIPT_DIR}/runfap.py",
|
||||
)
|
||||
|
||||
if not env["VERBOSE"]:
|
||||
env.SetDefault(
|
||||
FAPDISTCOMSTR="\tFAPDIST\t${TARGET}",
|
||||
@@ -256,6 +269,10 @@ def generate(env, **kw):
|
||||
APPCHECK_COMSTR="\tAPPCHK\t${SOURCE}",
|
||||
)
|
||||
|
||||
env.SetDefault(
|
||||
EXT_APPS={}, # appid -> FlipperExternalAppInfo
|
||||
)
|
||||
|
||||
env.AddMethod(BuildAppElf)
|
||||
env.AddMethod(GetExtAppFromPath)
|
||||
env.Append(
|
||||
|
Reference in New Issue
Block a user