mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 20:49:49 +04:00
Merge branch 'ofw_dev' into dev
This commit is contained in:
@@ -1,25 +1,118 @@
|
||||
from ansi.color import fg
|
||||
from fbt.appmanifest import (
|
||||
ApplicationsCGenerator,
|
||||
AppManager,
|
||||
AppBuildset,
|
||||
FlipperApplication,
|
||||
FlipperAppType,
|
||||
FlipperManifestException,
|
||||
)
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Errors import StopError
|
||||
from SCons.Warnings import WarningOnByDefault, warn
|
||||
from SCons.Script import GetOption
|
||||
from SCons.Warnings import WarningOnByDefault, warn
|
||||
|
||||
# Adding objects for application management to env
|
||||
# AppManager env["APPMGR"] - loads all manifests; manages list of known apps
|
||||
# AppBuildset env["APPBUILD"] - contains subset of apps, filtered for current config
|
||||
|
||||
|
||||
class ApplicationsCGenerator:
|
||||
APP_TYPE_MAP = {
|
||||
FlipperAppType.SERVICE: ("FlipperInternalApplication", "FLIPPER_SERVICES"),
|
||||
FlipperAppType.SYSTEM: ("FlipperInternalApplication", "FLIPPER_SYSTEM_APPS"),
|
||||
FlipperAppType.APP: ("FlipperInternalApplication", "FLIPPER_APPS"),
|
||||
FlipperAppType.DEBUG: ("FlipperInternalApplication", "FLIPPER_DEBUG_APPS"),
|
||||
FlipperAppType.SETTINGS: (
|
||||
"FlipperInternalApplication",
|
||||
"FLIPPER_SETTINGS_APPS",
|
||||
),
|
||||
FlipperAppType.STARTUP: (
|
||||
"FlipperInternalOnStartHook",
|
||||
"FLIPPER_ON_SYSTEM_START",
|
||||
),
|
||||
}
|
||||
|
||||
APP_EXTERNAL_TYPE = (
|
||||
"FlipperExternalApplication",
|
||||
"FLIPPER_EXTERNAL_APPS",
|
||||
)
|
||||
|
||||
def __init__(self, buildset: AppBuildset, autorun_app: str = ""):
|
||||
self.buildset = buildset
|
||||
self.autorun = autorun_app
|
||||
|
||||
def get_app_ep_forward(self, app: FlipperApplication):
|
||||
if app.apptype == FlipperAppType.STARTUP:
|
||||
return f"extern void {app.entry_point}();"
|
||||
return f"extern int32_t {app.entry_point}(void* p);"
|
||||
|
||||
def get_app_descr(self, app: FlipperApplication):
|
||||
if app.apptype == FlipperAppType.STARTUP:
|
||||
return app.entry_point
|
||||
return f"""
|
||||
{{.app = {app.entry_point},
|
||||
.name = "{app.name}",
|
||||
.appid = "{app.appid}",
|
||||
.stack_size = {app.stack_size},
|
||||
.icon = {f"&{app.icon}" if app.icon else "NULL"},
|
||||
.flags = {'|'.join(f"FlipperInternalApplicationFlag{flag}" for flag in app.flags)} }}"""
|
||||
|
||||
def get_external_app_descr(self, app: FlipperApplication):
|
||||
app_path = "/ext/apps"
|
||||
if app.fap_category:
|
||||
app_path += f"/{app.fap_category}"
|
||||
app_path += f"/{app.appid}.fap"
|
||||
return f"""
|
||||
{{
|
||||
.name = "{app.name}",
|
||||
.icon = {f"&{app.icon}" if app.icon else "NULL"},
|
||||
.path = "{app_path}" }}"""
|
||||
|
||||
def generate(self):
|
||||
contents = [
|
||||
'#include "applications.h"',
|
||||
"#include <assets_icons.h>",
|
||||
f'const char* FLIPPER_AUTORUN_APP_NAME = "{self.autorun}";',
|
||||
]
|
||||
for apptype in self.APP_TYPE_MAP:
|
||||
contents.extend(
|
||||
map(self.get_app_ep_forward, self.buildset.get_apps_of_type(apptype))
|
||||
)
|
||||
entry_type, entry_block = self.APP_TYPE_MAP[apptype]
|
||||
contents.append(f"const {entry_type} {entry_block}[] = {{")
|
||||
contents.append(
|
||||
",\n".join(
|
||||
map(self.get_app_descr, self.buildset.get_apps_of_type(apptype))
|
||||
)
|
||||
)
|
||||
contents.append("};")
|
||||
contents.append(
|
||||
f"const size_t {entry_block}_COUNT = COUNT_OF({entry_block});"
|
||||
)
|
||||
|
||||
archive_app = self.buildset.get_apps_of_type(FlipperAppType.ARCHIVE)
|
||||
if archive_app:
|
||||
contents.extend(
|
||||
[
|
||||
self.get_app_ep_forward(archive_app[0]),
|
||||
f"const FlipperInternalApplication FLIPPER_ARCHIVE = {self.get_app_descr(archive_app[0])};",
|
||||
]
|
||||
)
|
||||
|
||||
entry_type, entry_block = self.APP_EXTERNAL_TYPE
|
||||
external_apps = self.buildset.get_apps_of_type(FlipperAppType.MENUEXTERNAL)
|
||||
contents.append(f"const {entry_type} {entry_block}[] = {{")
|
||||
contents.append(",\n".join(map(self.get_external_app_descr, external_apps)))
|
||||
contents.append("};")
|
||||
contents.append(f"const size_t {entry_block}_COUNT = COUNT_OF({entry_block});")
|
||||
|
||||
return "\n".join(contents)
|
||||
|
||||
|
||||
def LoadAppManifest(env, entry):
|
||||
try:
|
||||
APP_MANIFEST_NAME = "application.fam"
|
||||
manifest_glob = entry.glob(APP_MANIFEST_NAME)
|
||||
manifest_glob = entry.glob(FlipperApplication.APP_MANIFEST_DEFAULT_NAME)
|
||||
if len(manifest_glob) == 0:
|
||||
try:
|
||||
disk_node = next(filter(lambda d: d.exists(), entry.get_all_rdirs()))
|
||||
@@ -27,7 +120,7 @@ def LoadAppManifest(env, entry):
|
||||
disk_node = entry
|
||||
|
||||
raise FlipperManifestException(
|
||||
f"App folder '{disk_node.abspath}': missing manifest ({APP_MANIFEST_NAME})"
|
||||
f"App folder '{disk_node.abspath}': missing manifest ({FlipperApplication.APP_MANIFEST_DEFAULT_NAME})"
|
||||
)
|
||||
|
||||
app_manifest_file_path = manifest_glob[0].rfile().abspath
|
||||
|
||||
@@ -58,7 +58,8 @@ class AppBuilder:
|
||||
)
|
||||
self.app_env.Append(
|
||||
CPPDEFINES=[
|
||||
("FAP_VERSION", f'"{".".join(map(str, self.app.fap_version))}"')
|
||||
("FAP_VERSION", f'\\"{".".join(map(str, self.app.fap_version))}\\"'),
|
||||
*self.app.cdefines,
|
||||
],
|
||||
)
|
||||
self.app_env.VariantDir(self.app_work_dir, self.app._appdir, duplicate=False)
|
||||
@@ -143,8 +144,8 @@ class AppBuilder:
|
||||
self.app._assets_dirs = [self.app._appdir.Dir(self.app.fap_file_assets)]
|
||||
|
||||
self.app_env.Append(
|
||||
LIBS=[*self.app.fap_libs, *self.private_libs],
|
||||
CPPPATH=[self.app_work_dir, self.app._appdir],
|
||||
LIBS=[*self.app.fap_libs, *self.private_libs, *self.app.fap_libs],
|
||||
CPPPATH=[self.app_env.Dir(self.app_work_dir), self.app._appdir],
|
||||
)
|
||||
|
||||
app_sources = self.app_env.GatherSources(
|
||||
@@ -472,7 +473,19 @@ def AddAppLaunchTarget(env, appname, launch_target_name):
|
||||
components = _gather_app_components(env, appname)
|
||||
target = env.PhonyTarget(
|
||||
launch_target_name,
|
||||
'${PYTHON3} "${APP_RUN_SCRIPT}" -p ${FLIP_PORT} ${EXTRA_ARGS} -s ${SOURCES} -t ${FLIPPER_FILE_TARGETS}',
|
||||
[
|
||||
[
|
||||
"${PYTHON3}",
|
||||
"${APP_RUN_SCRIPT}",
|
||||
"-p",
|
||||
"${FLIP_PORT}",
|
||||
"${EXTRA_ARGS}",
|
||||
"-s",
|
||||
"${SOURCES}",
|
||||
"-t",
|
||||
"${FLIPPER_FILE_TARGETS}",
|
||||
]
|
||||
],
|
||||
source=components.deploy_sources.values(),
|
||||
FLIPPER_FILE_TARGETS=components.deploy_sources.keys(),
|
||||
EXTRA_ARGS=components.extra_launch_args,
|
||||
|
||||
@@ -285,7 +285,20 @@ def generate(env, **kw):
|
||||
"$SDK_AMALGAMATE_HEADER_COMSTR",
|
||||
),
|
||||
Action(
|
||||
"$CC -o $TARGET -E -P $CCFLAGS $_CCCOMCOM $SDK_PP_FLAGS -MMD ${TARGET}.c",
|
||||
[
|
||||
[
|
||||
"$CC",
|
||||
"-o",
|
||||
"$TARGET",
|
||||
"-E",
|
||||
"-P",
|
||||
"$CCFLAGS",
|
||||
"$_CCCOMCOM",
|
||||
"$SDK_PP_FLAGS",
|
||||
"-MMD",
|
||||
"${TARGET}.c",
|
||||
]
|
||||
],
|
||||
"$SDK_AMALGAMATE_PP_COMSTR",
|
||||
),
|
||||
],
|
||||
|
||||
@@ -19,10 +19,22 @@ def generate(env):
|
||||
BUILDERS={
|
||||
"VersionBuilder": Builder(
|
||||
action=Action(
|
||||
'${PYTHON3} "${VERSION_SCRIPT}" generate '
|
||||
"-t ${TARGET_HW} -fw-origin ${FIRMWARE_ORIGIN} "
|
||||
'-o ${TARGET.dir.posix} --dir "${ROOT_DIR}"',
|
||||
"${VERSIONCOMSTR}",
|
||||
[
|
||||
[
|
||||
"${PYTHON3}",
|
||||
"${VERSION_SCRIPT}",
|
||||
"generate",
|
||||
"-t",
|
||||
"${TARGET_HW}",
|
||||
"--fw-origin",
|
||||
"${FIRMWARE_ORIGIN}",
|
||||
"-o",
|
||||
"${TARGET.dir.posix}",
|
||||
"--dir",
|
||||
"${ROOT_DIR}",
|
||||
"${VERSIONCOMSTR}",
|
||||
]
|
||||
]
|
||||
),
|
||||
emitter=_version_emitter,
|
||||
),
|
||||
|
||||
@@ -25,7 +25,7 @@ def generate(env):
|
||||
BUILDERS={
|
||||
"HEXBuilder": Builder(
|
||||
action=Action(
|
||||
'${OBJCOPY} -O ihex "${SOURCE}" "${TARGET}"',
|
||||
[["${OBJCOPY}", "-O", "ihex", "${SOURCE}", "${TARGET}"]],
|
||||
"${HEXCOMSTR}",
|
||||
),
|
||||
suffix=".hex",
|
||||
@@ -33,7 +33,7 @@ def generate(env):
|
||||
),
|
||||
"BINBuilder": Builder(
|
||||
action=Action(
|
||||
'${OBJCOPY} -O binary -S "${SOURCE}" "${TARGET}"',
|
||||
[["${OBJCOPY}", "-O", "binary", "-S", "${SOURCE}", "${TARGET}"]],
|
||||
"${BINCOMSTR}",
|
||||
),
|
||||
suffix=".bin",
|
||||
@@ -41,7 +41,20 @@ def generate(env):
|
||||
),
|
||||
"DFUBuilder": Builder(
|
||||
action=Action(
|
||||
'${PYTHON3} "${BIN2DFU}" -i "${SOURCE}" -o "${TARGET}" -a ${IMAGE_BASE_ADDRESS} -l "Flipper Zero F${TARGET_HW}"',
|
||||
[
|
||||
[
|
||||
"${PYTHON3}",
|
||||
"${BIN2DFU}",
|
||||
"-i",
|
||||
"${SOURCE}",
|
||||
"-o",
|
||||
"${TARGET}",
|
||||
"-a",
|
||||
"${IMAGE_BASE_ADDRESS}",
|
||||
"-l",
|
||||
"Flipper Zero F${TARGET_HW}",
|
||||
]
|
||||
],
|
||||
"${DFUCOMSTR}",
|
||||
),
|
||||
suffix=".dfu",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Defaults import Touch
|
||||
from SCons.Action import Action
|
||||
|
||||
|
||||
def generate(env):
|
||||
@@ -9,13 +10,21 @@ def generate(env):
|
||||
"-auto",
|
||||
"-exit",
|
||||
],
|
||||
JFLASHCOM="${JFLASH} -openprj${JFLASHPROJECT} -open${SOURCE},${JFLASHADDR} ${JFLASHFLAGS}",
|
||||
)
|
||||
env.Append(
|
||||
BUILDERS={
|
||||
"JFlash": Builder(
|
||||
action=[
|
||||
"${JFLASHCOM}",
|
||||
Action(
|
||||
[
|
||||
[
|
||||
"${JFLASH}",
|
||||
"-openprj${JFLASHPROJECT}",
|
||||
"-open${SOURCE},${JFLASHADDR}",
|
||||
"${JFLASHFLAGS}",
|
||||
]
|
||||
]
|
||||
),
|
||||
Touch("${TARGET}"),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -6,13 +6,12 @@ def generate(env):
|
||||
env.SetDefault(
|
||||
OBJDUMP="objdump",
|
||||
OBJDUMPFLAGS=[],
|
||||
OBJDUMPCOM="$OBJDUMP $OBJDUMPFLAGS -S $SOURCES > $TARGET",
|
||||
)
|
||||
env.Append(
|
||||
BUILDERS={
|
||||
"ObjDump": Builder(
|
||||
action=Action(
|
||||
"${OBJDUMPCOM}",
|
||||
[["$OBJDUMP", "$OBJDUMPFLAGS", "-S", "$SOURCES", ">", "$TARGET"]],
|
||||
"${OBJDUMPCOMSTR}",
|
||||
),
|
||||
suffix=".lst",
|
||||
|
||||
@@ -5,6 +5,7 @@ from SCons.Defaults import Touch
|
||||
|
||||
__OPENOCD_BIN = "openocd"
|
||||
|
||||
# TODO: FL-3663: rework argument passing to lists
|
||||
_oocd_action = Action(
|
||||
"${OPENOCD} ${OPENOCD_OPTS} ${OPENOCD_COMMAND}",
|
||||
"${OPENOCDCOMSTR}",
|
||||
|
||||
@@ -79,7 +79,17 @@ def generate(env):
|
||||
BUILDERS={
|
||||
"PVSCheck": Builder(
|
||||
action=Action(
|
||||
'${PVSCHECKBIN} analyze ${PVSOPTIONS} -f "${SOURCE}" -o "${TARGET}"',
|
||||
[
|
||||
[
|
||||
"${PVSCHECKBIN}",
|
||||
"analyze",
|
||||
"${PVSOPTIONS}",
|
||||
"-f",
|
||||
"${SOURCE}",
|
||||
"-o",
|
||||
"${TARGET}",
|
||||
]
|
||||
],
|
||||
"${PVSCHECKCOMSTR}",
|
||||
),
|
||||
suffix=".log",
|
||||
@@ -92,7 +102,17 @@ def generate(env):
|
||||
# PlogConverter.exe and plog-converter have different behavior
|
||||
Mkdir("${TARGET.dir}") if env["PLATFORM"] == "win32" else None,
|
||||
Action(_set_browser_action, None),
|
||||
'${PVSCONVBIN} ${PVSCONVOPTIONS} "${SOURCE}" -o "${REPORT_DIR}"',
|
||||
Action(
|
||||
[
|
||||
[
|
||||
"${PVSCONVBIN}",
|
||||
"${PVSCONVOPTIONS}",
|
||||
"${SOURCE}",
|
||||
"-o",
|
||||
"${REPORT_DIR}",
|
||||
]
|
||||
]
|
||||
),
|
||||
],
|
||||
"${PVSCONVCOMSTR}",
|
||||
),
|
||||
|
||||
@@ -6,13 +6,12 @@ def generate(env):
|
||||
env.SetDefault(
|
||||
STRIP="strip",
|
||||
STRIPFLAGS=[],
|
||||
STRIPCOM="$STRIP $STRIPFLAGS $SOURCES -o $TARGET",
|
||||
)
|
||||
env.Append(
|
||||
BUILDERS={
|
||||
"ELFStripper": Builder(
|
||||
action=Action(
|
||||
"${STRIPCOM}",
|
||||
[["$STRIP", "$STRIPFLAGS", "$SOURCES", "-o", "$TARGET"]],
|
||||
"${STRIPCOMSTR}",
|
||||
),
|
||||
suffix=".elf",
|
||||
|
||||
Reference in New Issue
Block a user