mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-01-03 10:48:47 +03:00
fbt: improvements (#3217)
* fbt: changed cdefines & lib handling for external apps; added extra checks for app manifest fields; moved around AppsC generator * fbt: commandline fixes for spaces in paths * fbt: fixed stringification for FAP_VERSION * fbt: Removed excessive quoting for gdb * docs: update for cdefines; fbt: typo fix * fbt: enforcing at least 2 components in app version= Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
457aa5331f
commit
98d5718ec9
36
SConstruct
36
SConstruct
@ -172,17 +172,19 @@ Alias("fap_dist", fap_dist)
|
|||||||
|
|
||||||
fap_deploy = distenv.PhonyTarget(
|
fap_deploy = distenv.PhonyTarget(
|
||||||
"fap_deploy",
|
"fap_deploy",
|
||||||
[
|
Action(
|
||||||
[
|
[
|
||||||
"${PYTHON3}",
|
[
|
||||||
"${FBT_SCRIPT_DIR}/storage.py",
|
"${PYTHON3}",
|
||||||
"-p",
|
"${FBT_SCRIPT_DIR}/storage.py",
|
||||||
"${FLIP_PORT}",
|
"-p",
|
||||||
"send",
|
"${FLIP_PORT}",
|
||||||
"${SOURCE}",
|
"send",
|
||||||
"/ext/apps",
|
"${SOURCE}",
|
||||||
|
"/ext/apps",
|
||||||
|
]
|
||||||
]
|
]
|
||||||
],
|
),
|
||||||
source=firmware_env.Dir(("${RESOURCES_ROOT}/apps")),
|
source=firmware_env.Dir(("${RESOURCES_ROOT}/apps")),
|
||||||
)
|
)
|
||||||
Depends(fap_deploy, firmware_env["FW_RESOURCES_MANIFEST"])
|
Depends(fap_deploy, firmware_env["FW_RESOURCES_MANIFEST"])
|
||||||
@ -261,7 +263,7 @@ distenv.PhonyTarget(
|
|||||||
distenv.PhonyTarget(
|
distenv.PhonyTarget(
|
||||||
"debug_other_blackmagic",
|
"debug_other_blackmagic",
|
||||||
"${GDBPYCOM}",
|
"${GDBPYCOM}",
|
||||||
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
|
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
|
||||||
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
||||||
GDBPYOPTS=debug_other_opts,
|
GDBPYOPTS=debug_other_opts,
|
||||||
)
|
)
|
||||||
@ -276,13 +278,13 @@ distenv.PhonyTarget(
|
|||||||
# Linter
|
# Linter
|
||||||
distenv.PhonyTarget(
|
distenv.PhonyTarget(
|
||||||
"lint",
|
"lint",
|
||||||
"${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}",
|
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "check", "${LINT_SOURCES}"]],
|
||||||
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
|
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
distenv.PhonyTarget(
|
distenv.PhonyTarget(
|
||||||
"format",
|
"format",
|
||||||
"${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}",
|
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "format", "${LINT_SOURCES}"]],
|
||||||
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
|
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -323,10 +325,14 @@ distenv.PhonyTarget(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Start Flipper CLI via PySerial's miniterm
|
# Start Flipper CLI via PySerial's miniterm
|
||||||
distenv.PhonyTarget("cli", "${PYTHON3} ${FBT_SCRIPT_DIR}/serial_cli.py -p ${FLIP_PORT}")
|
distenv.PhonyTarget(
|
||||||
|
"cli", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/serial_cli.py", "-p", "${FLIP_PORT}"]]
|
||||||
|
)
|
||||||
|
|
||||||
# Update WiFi devboard firmware
|
# Update WiFi devboard firmware
|
||||||
distenv.PhonyTarget("devboard_flash", "${PYTHON3} ${FBT_SCRIPT_DIR}/wifi_board.py")
|
distenv.PhonyTarget(
|
||||||
|
"devboard_flash", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/wifi_board.py"]]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Find blackmagic probe
|
# Find blackmagic probe
|
||||||
@ -361,5 +367,5 @@ distenv.Alias("vscode_dist", vscode_dist)
|
|||||||
# Configure shell with build tools
|
# Configure shell with build tools
|
||||||
distenv.PhonyTarget(
|
distenv.PhonyTarget(
|
||||||
"env",
|
"env",
|
||||||
"@echo $( ${FBT_SCRIPT_DIR}/toolchain/fbtenv.sh $)",
|
"@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)",
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,6 @@ App(
|
|||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
targets=["f7"],
|
targets=["f7"],
|
||||||
entry_point="accessor_app",
|
entry_point="accessor_app",
|
||||||
cdefines=["APP_ACCESSOR"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=4 * 1024,
|
stack_size=4 * 1024,
|
||||||
order=40,
|
order=40,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="Battery Test",
|
name="Battery Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="battery_test_app",
|
entry_point="battery_test_app",
|
||||||
cdefines=["APP_BATTERY_TEST"],
|
|
||||||
requires=[
|
requires=[
|
||||||
"gui",
|
"gui",
|
||||||
"power",
|
"power",
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="Blink Test",
|
name="Blink Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="blink_test_app",
|
entry_point="blink_test_app",
|
||||||
cdefines=["APP_BLINK"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
order=10,
|
order=10,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="CCID Debug",
|
name="CCID Debug",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="ccid_test_app",
|
entry_point="ccid_test_app",
|
||||||
cdefines=["CCID_TEST"],
|
|
||||||
requires=[
|
requires=[
|
||||||
"gui",
|
"gui",
|
||||||
],
|
],
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="Crash Test",
|
name="Crash Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="crash_test_app",
|
entry_point="crash_test_app",
|
||||||
cdefines=["APP_CRASH_TEST"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
fap_category="Debug",
|
fap_category="Debug",
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="Display Test",
|
name="Display Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="display_test_app",
|
entry_point="display_test_app",
|
||||||
cdefines=["APP_DISPLAY_TEST"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
fap_libs=["misc"],
|
fap_libs=["misc"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="File Browser Test",
|
name="File Browser Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="file_browser_app",
|
entry_point="file_browser_app",
|
||||||
cdefines=["APP_FILE_BROWSER_TEST"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=2 * 1024,
|
stack_size=2 * 1024,
|
||||||
order=150,
|
order=150,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="Keypad Test",
|
name="Keypad Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="keypad_test_app",
|
entry_point="keypad_test_app",
|
||||||
cdefines=["APP_KEYPAD_TEST"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
order=30,
|
order=30,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="Locale Test",
|
name="Locale Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="locale_test_app",
|
entry_point="locale_test_app",
|
||||||
cdefines=["APP_LOCALE"],
|
|
||||||
requires=["gui", "locale"],
|
requires=["gui", "locale"],
|
||||||
stack_size=2 * 1024,
|
stack_size=2 * 1024,
|
||||||
order=70,
|
order=70,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="Text Box Test",
|
name="Text Box Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="text_box_test_app",
|
entry_point="text_box_test_app",
|
||||||
cdefines=["APP_TEXT_BOX_TEST"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
order=140,
|
order=140,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="UART Echo",
|
name="UART Echo",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="uart_echo_app",
|
entry_point="uart_echo_app",
|
||||||
cdefines=["APP_UART_ECHO"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=2 * 1024,
|
stack_size=2 * 1024,
|
||||||
order=70,
|
order=70,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="USB Mouse Demo",
|
name="USB Mouse Demo",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="usb_mouse_app",
|
entry_point="usb_mouse_app",
|
||||||
cdefines=["APP_USB_MOUSE"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
order=60,
|
order=60,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="USB Test",
|
name="USB Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="usb_test_app",
|
entry_point="usb_test_app",
|
||||||
cdefines=["APP_USB_TEST"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
order=50,
|
order=50,
|
||||||
|
@ -3,7 +3,6 @@ App(
|
|||||||
name="Vibro Test",
|
name="Vibro Test",
|
||||||
apptype=FlipperAppType.DEBUG,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="vibro_test_app",
|
entry_point="vibro_test_app",
|
||||||
cdefines=["APP_VIBRO_TEST"],
|
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
order=20,
|
order=20,
|
||||||
|
@ -32,7 +32,7 @@ Only two parameters are mandatory: **_appid_** and **_apptype_**. Others are opt
|
|||||||
- **name**: name displayed in menus.
|
- **name**: name displayed in menus.
|
||||||
- **entry_point**: C function to be used as the application's entry point. Note that C++ function names are mangled, so you need to wrap them in `extern "C"` to use them as entry points.
|
- **entry_point**: C function to be used as the application's entry point. Note that C++ function names are mangled, so you need to wrap them in `extern "C"` to use them as entry points.
|
||||||
- **flags**: internal flags for system apps. Do not use.
|
- **flags**: internal flags for system apps. Do not use.
|
||||||
- **cdefines**: C preprocessor definitions to declare globally for other apps when the current application is included in the active build configuration.
|
- **cdefines**: C preprocessor definitions to declare globally for other apps when the current application is included in the active build configuration. **For external applications**: specified definitions are used when building the application itself.
|
||||||
- **requires**: list of application IDs to include in the build configuration when the current application is referenced in the list of applications to build.
|
- **requires**: list of application IDs to include in the build configuration when the current application is referenced in the list of applications to build.
|
||||||
- **conflicts**: list of application IDs with which the current application conflicts. If any of them is found in the constructed application list, **`fbt`** will abort the firmware build process.
|
- **conflicts**: list of application IDs with which the current application conflicts. If any of them is found in the constructed application list, **`fbt`** will abort the firmware build process.
|
||||||
- **provides**: functionally identical to **_requires_** field.
|
- **provides**: functionally identical to **_requires_** field.
|
||||||
|
@ -219,7 +219,7 @@ AddPostAction(fwelf, fwenv["APPBUILD_DUMP"])
|
|||||||
AddPostAction(
|
AddPostAction(
|
||||||
fwelf,
|
fwelf,
|
||||||
Action(
|
Action(
|
||||||
'${PYTHON3} "${BIN_SIZE_SCRIPT}" elf ${TARGET}',
|
[["${PYTHON3}", "${BIN_SIZE_SCRIPT}", "elf", "${TARGET}"]],
|
||||||
"Firmware size",
|
"Firmware size",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -229,7 +229,7 @@ fwhex = fwenv["FW_HEX"] = fwenv.HEXBuilder("${FIRMWARE_BUILD_CFG}")
|
|||||||
fwbin = fwenv["FW_BIN"] = fwenv.BINBuilder("${FIRMWARE_BUILD_CFG}")
|
fwbin = fwenv["FW_BIN"] = fwenv.BINBuilder("${FIRMWARE_BUILD_CFG}")
|
||||||
AddPostAction(
|
AddPostAction(
|
||||||
fwbin,
|
fwbin,
|
||||||
Action('@${PYTHON3} "${BIN_SIZE_SCRIPT}" bin ${TARGET}'),
|
Action([["@${PYTHON3}", "${BIN_SIZE_SCRIPT}", "bin", "${TARGET}"]]),
|
||||||
)
|
)
|
||||||
|
|
||||||
fwdfu = fwenv["FW_DFU"] = fwenv.DFUBuilder("${FIRMWARE_BUILD_CFG}")
|
fwdfu = fwenv["FW_DFU"] = fwenv.DFUBuilder("${FIRMWARE_BUILD_CFG}")
|
||||||
|
@ -33,6 +33,8 @@ class FlipperAppType(Enum):
|
|||||||
@dataclass
|
@dataclass
|
||||||
class FlipperApplication:
|
class FlipperApplication:
|
||||||
APP_ID_REGEX: ClassVar[re.Pattern] = re.compile(r"^[a-z0-9_]+$")
|
APP_ID_REGEX: ClassVar[re.Pattern] = re.compile(r"^[a-z0-9_]+$")
|
||||||
|
PRIVATE_FIELD_PREFIX: ClassVar[str] = "_"
|
||||||
|
APP_MANIFEST_DEFAULT_NAME: ClassVar[str] = "application.fam"
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ExternallyBuiltFile:
|
class ExternallyBuiltFile:
|
||||||
@ -48,8 +50,6 @@ class FlipperApplication:
|
|||||||
cdefines: List[str] = field(default_factory=list)
|
cdefines: List[str] = field(default_factory=list)
|
||||||
cincludes: List[str] = field(default_factory=list)
|
cincludes: List[str] = field(default_factory=list)
|
||||||
|
|
||||||
PRIVATE_FIELD_PREFIX = "_"
|
|
||||||
|
|
||||||
appid: str
|
appid: str
|
||||||
apptype: FlipperAppType
|
apptype: FlipperAppType
|
||||||
name: Optional[str] = ""
|
name: Optional[str] = ""
|
||||||
@ -117,8 +117,10 @@ class FlipperApplication:
|
|||||||
self.fap_version = tuple(int(v) for v in self.fap_version.split("."))
|
self.fap_version = tuple(int(v) for v in self.fap_version.split("."))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise FlipperManifestException(
|
raise FlipperManifestException(
|
||||||
f"Invalid version string '{self.fap_version}'. Must be in the form 'major.minor'"
|
f"Invalid version '{self.fap_version}'. Must be in the form 'major.minor'"
|
||||||
)
|
)
|
||||||
|
if len(self.fap_version) < 2:
|
||||||
|
raise ValueError("Not enough version components")
|
||||||
|
|
||||||
|
|
||||||
class AppManager:
|
class AppManager:
|
||||||
@ -155,11 +157,20 @@ class AppManager:
|
|||||||
raise FlipperManifestException(
|
raise FlipperManifestException(
|
||||||
f"App {kw.get('appid')} cannot have fal_embedded set"
|
f"App {kw.get('appid')} cannot have fal_embedded set"
|
||||||
)
|
)
|
||||||
# Harmless - cdefines for external apps are meaningless
|
|
||||||
# if apptype == FlipperAppType.EXTERNAL and kw.get("cdefines"):
|
if apptype in AppBuildset.dist_app_types:
|
||||||
# raise FlipperManifestException(
|
# For distributing .fap's resources, there's "fap_file_assets"
|
||||||
# f"External app {kw.get('appid')} must not have 'cdefines' in manifest"
|
for app_property in ("resources",):
|
||||||
# )
|
if kw.get(app_property):
|
||||||
|
raise FlipperManifestException(
|
||||||
|
f"App {kw.get('appid')} of type {apptype} cannot have '{app_property}' in manifest"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for app_property in ("fap_extbuild", "fap_private_libs", "fap_icon_assets"):
|
||||||
|
if kw.get(app_property):
|
||||||
|
raise FlipperManifestException(
|
||||||
|
f"App {kw.get('appid')} of type {apptype} must not have '{app_property}' in manifest"
|
||||||
|
)
|
||||||
|
|
||||||
def load_manifest(self, app_manifest_path: str, app_dir_node: object):
|
def load_manifest(self, app_manifest_path: str, app_dir_node: object):
|
||||||
if not os.path.exists(app_manifest_path):
|
if not os.path.exists(app_manifest_path):
|
||||||
@ -241,12 +252,21 @@ class AppBuildset:
|
|||||||
FlipperAppType.STARTUP,
|
FlipperAppType.STARTUP,
|
||||||
)
|
)
|
||||||
EXTERNAL_APP_TYPES_MAP = {
|
EXTERNAL_APP_TYPES_MAP = {
|
||||||
|
# AppType -> bool: true if always deploy, false if obey app set
|
||||||
FlipperAppType.EXTERNAL: True,
|
FlipperAppType.EXTERNAL: True,
|
||||||
FlipperAppType.PLUGIN: True,
|
FlipperAppType.PLUGIN: True,
|
||||||
FlipperAppType.DEBUG: True,
|
FlipperAppType.DEBUG: True,
|
||||||
FlipperAppType.MENUEXTERNAL: False,
|
FlipperAppType.MENUEXTERNAL: False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@property
|
||||||
|
def dist_app_types(cls):
|
||||||
|
"""Applications that are installed on SD card"""
|
||||||
|
return list(
|
||||||
|
entry[0] for entry in cls.EXTERNAL_APP_TYPES_MAP.items() if entry[1]
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def print_writer(message):
|
def print_writer(message):
|
||||||
print(message)
|
print(message)
|
||||||
@ -432,96 +452,3 @@ class AppBuildset:
|
|||||||
for source_type in app.sources
|
for source_type in app.sources
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
@ -1,25 +1,118 @@
|
|||||||
from ansi.color import fg
|
from ansi.color import fg
|
||||||
from fbt.appmanifest import (
|
from fbt.appmanifest import (
|
||||||
ApplicationsCGenerator,
|
|
||||||
AppManager,
|
AppManager,
|
||||||
|
AppBuildset,
|
||||||
|
FlipperApplication,
|
||||||
FlipperAppType,
|
FlipperAppType,
|
||||||
FlipperManifestException,
|
FlipperManifestException,
|
||||||
)
|
)
|
||||||
from SCons.Action import Action
|
from SCons.Action import Action
|
||||||
from SCons.Builder import Builder
|
from SCons.Builder import Builder
|
||||||
from SCons.Errors import StopError
|
from SCons.Errors import StopError
|
||||||
from SCons.Warnings import WarningOnByDefault, warn
|
|
||||||
from SCons.Script import GetOption
|
from SCons.Script import GetOption
|
||||||
|
from SCons.Warnings import WarningOnByDefault, warn
|
||||||
|
|
||||||
# Adding objects for application management to env
|
# Adding objects for application management to env
|
||||||
# AppManager env["APPMGR"] - loads all manifests; manages list of known apps
|
# AppManager env["APPMGR"] - loads all manifests; manages list of known apps
|
||||||
# AppBuildset env["APPBUILD"] - contains subset of apps, filtered for current config
|
# 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):
|
def LoadAppManifest(env, entry):
|
||||||
try:
|
try:
|
||||||
APP_MANIFEST_NAME = "application.fam"
|
manifest_glob = entry.glob(FlipperApplication.APP_MANIFEST_DEFAULT_NAME)
|
||||||
manifest_glob = entry.glob(APP_MANIFEST_NAME)
|
|
||||||
if len(manifest_glob) == 0:
|
if len(manifest_glob) == 0:
|
||||||
try:
|
try:
|
||||||
disk_node = next(filter(lambda d: d.exists(), entry.get_all_rdirs()))
|
disk_node = next(filter(lambda d: d.exists(), entry.get_all_rdirs()))
|
||||||
@ -27,7 +120,7 @@ def LoadAppManifest(env, entry):
|
|||||||
disk_node = entry
|
disk_node = entry
|
||||||
|
|
||||||
raise FlipperManifestException(
|
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
|
app_manifest_file_path = manifest_glob[0].rfile().abspath
|
||||||
|
@ -58,7 +58,8 @@ class AppBuilder:
|
|||||||
)
|
)
|
||||||
self.app_env.Append(
|
self.app_env.Append(
|
||||||
CPPDEFINES=[
|
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)
|
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._assets_dirs = [self.app._appdir.Dir(self.app.fap_file_assets)]
|
||||||
|
|
||||||
self.app_env.Append(
|
self.app_env.Append(
|
||||||
LIBS=[*self.app.fap_libs, *self.private_libs],
|
LIBS=[*self.app.fap_libs, *self.private_libs, *self.app.fap_libs],
|
||||||
CPPPATH=[self.app_work_dir, self.app._appdir],
|
CPPPATH=[self.app_env.Dir(self.app_work_dir), self.app._appdir],
|
||||||
)
|
)
|
||||||
|
|
||||||
app_sources = self.app_env.GatherSources(
|
app_sources = self.app_env.GatherSources(
|
||||||
@ -472,7 +473,19 @@ def AddAppLaunchTarget(env, appname, launch_target_name):
|
|||||||
components = _gather_app_components(env, appname)
|
components = _gather_app_components(env, appname)
|
||||||
target = env.PhonyTarget(
|
target = env.PhonyTarget(
|
||||||
launch_target_name,
|
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(),
|
source=components.deploy_sources.values(),
|
||||||
FLIPPER_FILE_TARGETS=components.deploy_sources.keys(),
|
FLIPPER_FILE_TARGETS=components.deploy_sources.keys(),
|
||||||
EXTRA_ARGS=components.extra_launch_args,
|
EXTRA_ARGS=components.extra_launch_args,
|
||||||
|
@ -285,7 +285,20 @@ def generate(env, **kw):
|
|||||||
"$SDK_AMALGAMATE_HEADER_COMSTR",
|
"$SDK_AMALGAMATE_HEADER_COMSTR",
|
||||||
),
|
),
|
||||||
Action(
|
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",
|
"$SDK_AMALGAMATE_PP_COMSTR",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -19,10 +19,22 @@ def generate(env):
|
|||||||
BUILDERS={
|
BUILDERS={
|
||||||
"VersionBuilder": Builder(
|
"VersionBuilder": Builder(
|
||||||
action=Action(
|
action=Action(
|
||||||
'${PYTHON3} "${VERSION_SCRIPT}" generate '
|
[
|
||||||
"-t ${TARGET_HW} -fw-origin ${FIRMWARE_ORIGIN} "
|
[
|
||||||
'-o ${TARGET.dir.posix} --dir "${ROOT_DIR}"',
|
"${PYTHON3}",
|
||||||
"${VERSIONCOMSTR}",
|
"${VERSION_SCRIPT}",
|
||||||
|
"generate",
|
||||||
|
"-t",
|
||||||
|
"${TARGET_HW}",
|
||||||
|
"--fw-origin",
|
||||||
|
"${FIRMWARE_ORIGIN}",
|
||||||
|
"-o",
|
||||||
|
"${TARGET.dir.posix}",
|
||||||
|
"--dir",
|
||||||
|
"${ROOT_DIR}",
|
||||||
|
"${VERSIONCOMSTR}",
|
||||||
|
]
|
||||||
|
]
|
||||||
),
|
),
|
||||||
emitter=_version_emitter,
|
emitter=_version_emitter,
|
||||||
),
|
),
|
||||||
|
@ -25,7 +25,7 @@ def generate(env):
|
|||||||
BUILDERS={
|
BUILDERS={
|
||||||
"HEXBuilder": Builder(
|
"HEXBuilder": Builder(
|
||||||
action=Action(
|
action=Action(
|
||||||
'${OBJCOPY} -O ihex "${SOURCE}" "${TARGET}"',
|
[["${OBJCOPY}", "-O", "ihex", "${SOURCE}", "${TARGET}"]],
|
||||||
"${HEXCOMSTR}",
|
"${HEXCOMSTR}",
|
||||||
),
|
),
|
||||||
suffix=".hex",
|
suffix=".hex",
|
||||||
@ -33,7 +33,7 @@ def generate(env):
|
|||||||
),
|
),
|
||||||
"BINBuilder": Builder(
|
"BINBuilder": Builder(
|
||||||
action=Action(
|
action=Action(
|
||||||
'${OBJCOPY} -O binary -S "${SOURCE}" "${TARGET}"',
|
[["${OBJCOPY}", "-O", "binary", "-S", "${SOURCE}", "${TARGET}"]],
|
||||||
"${BINCOMSTR}",
|
"${BINCOMSTR}",
|
||||||
),
|
),
|
||||||
suffix=".bin",
|
suffix=".bin",
|
||||||
@ -41,7 +41,20 @@ def generate(env):
|
|||||||
),
|
),
|
||||||
"DFUBuilder": Builder(
|
"DFUBuilder": Builder(
|
||||||
action=Action(
|
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}",
|
"${DFUCOMSTR}",
|
||||||
),
|
),
|
||||||
suffix=".dfu",
|
suffix=".dfu",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from SCons.Builder import Builder
|
from SCons.Builder import Builder
|
||||||
from SCons.Defaults import Touch
|
from SCons.Defaults import Touch
|
||||||
|
from SCons.Action import Action
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
@ -9,13 +10,21 @@ def generate(env):
|
|||||||
"-auto",
|
"-auto",
|
||||||
"-exit",
|
"-exit",
|
||||||
],
|
],
|
||||||
JFLASHCOM="${JFLASH} -openprj${JFLASHPROJECT} -open${SOURCE},${JFLASHADDR} ${JFLASHFLAGS}",
|
|
||||||
)
|
)
|
||||||
env.Append(
|
env.Append(
|
||||||
BUILDERS={
|
BUILDERS={
|
||||||
"JFlash": Builder(
|
"JFlash": Builder(
|
||||||
action=[
|
action=[
|
||||||
"${JFLASHCOM}",
|
Action(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"${JFLASH}",
|
||||||
|
"-openprj${JFLASHPROJECT}",
|
||||||
|
"-open${SOURCE},${JFLASHADDR}",
|
||||||
|
"${JFLASHFLAGS}",
|
||||||
|
]
|
||||||
|
]
|
||||||
|
),
|
||||||
Touch("${TARGET}"),
|
Touch("${TARGET}"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -6,13 +6,12 @@ def generate(env):
|
|||||||
env.SetDefault(
|
env.SetDefault(
|
||||||
OBJDUMP="objdump",
|
OBJDUMP="objdump",
|
||||||
OBJDUMPFLAGS=[],
|
OBJDUMPFLAGS=[],
|
||||||
OBJDUMPCOM="$OBJDUMP $OBJDUMPFLAGS -S $SOURCES > $TARGET",
|
|
||||||
)
|
)
|
||||||
env.Append(
|
env.Append(
|
||||||
BUILDERS={
|
BUILDERS={
|
||||||
"ObjDump": Builder(
|
"ObjDump": Builder(
|
||||||
action=Action(
|
action=Action(
|
||||||
"${OBJDUMPCOM}",
|
[["$OBJDUMP", "$OBJDUMPFLAGS", "-S", "$SOURCES", ">", "$TARGET"]],
|
||||||
"${OBJDUMPCOMSTR}",
|
"${OBJDUMPCOMSTR}",
|
||||||
),
|
),
|
||||||
suffix=".lst",
|
suffix=".lst",
|
||||||
|
@ -5,6 +5,7 @@ from SCons.Defaults import Touch
|
|||||||
|
|
||||||
__OPENOCD_BIN = "openocd"
|
__OPENOCD_BIN = "openocd"
|
||||||
|
|
||||||
|
# TODO: FL-3663: rework argument passing to lists
|
||||||
_oocd_action = Action(
|
_oocd_action = Action(
|
||||||
"${OPENOCD} ${OPENOCD_OPTS} ${OPENOCD_COMMAND}",
|
"${OPENOCD} ${OPENOCD_OPTS} ${OPENOCD_COMMAND}",
|
||||||
"${OPENOCDCOMSTR}",
|
"${OPENOCDCOMSTR}",
|
||||||
|
@ -79,7 +79,17 @@ def generate(env):
|
|||||||
BUILDERS={
|
BUILDERS={
|
||||||
"PVSCheck": Builder(
|
"PVSCheck": Builder(
|
||||||
action=Action(
|
action=Action(
|
||||||
'${PVSCHECKBIN} analyze ${PVSOPTIONS} -f "${SOURCE}" -o "${TARGET}"',
|
[
|
||||||
|
[
|
||||||
|
"${PVSCHECKBIN}",
|
||||||
|
"analyze",
|
||||||
|
"${PVSOPTIONS}",
|
||||||
|
"-f",
|
||||||
|
"${SOURCE}",
|
||||||
|
"-o",
|
||||||
|
"${TARGET}",
|
||||||
|
]
|
||||||
|
],
|
||||||
"${PVSCHECKCOMSTR}",
|
"${PVSCHECKCOMSTR}",
|
||||||
),
|
),
|
||||||
suffix=".log",
|
suffix=".log",
|
||||||
@ -92,7 +102,17 @@ def generate(env):
|
|||||||
# PlogConverter.exe and plog-converter have different behavior
|
# PlogConverter.exe and plog-converter have different behavior
|
||||||
Mkdir("${TARGET.dir}") if env["PLATFORM"] == "win32" else None,
|
Mkdir("${TARGET.dir}") if env["PLATFORM"] == "win32" else None,
|
||||||
Action(_set_browser_action, None),
|
Action(_set_browser_action, None),
|
||||||
'${PVSCONVBIN} ${PVSCONVOPTIONS} "${SOURCE}" -o "${REPORT_DIR}"',
|
Action(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"${PVSCONVBIN}",
|
||||||
|
"${PVSCONVOPTIONS}",
|
||||||
|
"${SOURCE}",
|
||||||
|
"-o",
|
||||||
|
"${REPORT_DIR}",
|
||||||
|
]
|
||||||
|
]
|
||||||
|
),
|
||||||
],
|
],
|
||||||
"${PVSCONVCOMSTR}",
|
"${PVSCONVCOMSTR}",
|
||||||
),
|
),
|
||||||
|
@ -6,13 +6,12 @@ def generate(env):
|
|||||||
env.SetDefault(
|
env.SetDefault(
|
||||||
STRIP="strip",
|
STRIP="strip",
|
||||||
STRIPFLAGS=[],
|
STRIPFLAGS=[],
|
||||||
STRIPCOM="$STRIP $STRIPFLAGS $SOURCES -o $TARGET",
|
|
||||||
)
|
)
|
||||||
env.Append(
|
env.Append(
|
||||||
BUILDERS={
|
BUILDERS={
|
||||||
"ELFStripper": Builder(
|
"ELFStripper": Builder(
|
||||||
action=Action(
|
action=Action(
|
||||||
"${STRIPCOM}",
|
[["$STRIP", "$STRIPFLAGS", "$SOURCES", "-o", "$TARGET"]],
|
||||||
"${STRIPCOMSTR}",
|
"${STRIPCOMSTR}",
|
||||||
),
|
),
|
||||||
suffix=".elf",
|
suffix=".elf",
|
||||||
|
@ -325,24 +325,26 @@ else:
|
|||||||
|
|
||||||
appenv.PhonyTarget(
|
appenv.PhonyTarget(
|
||||||
"cli",
|
"cli",
|
||||||
'${PYTHON3} "${FBT_SCRIPT_DIR}/serial_cli.py" -p ${FLIP_PORT}',
|
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/serial_cli.py", "-p", "${FLIP_PORT}"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update WiFi devboard firmware
|
# Update WiFi devboard firmware
|
||||||
dist_env.PhonyTarget("devboard_flash", "${PYTHON3} ${FBT_SCRIPT_DIR}/wifi_board.py")
|
dist_env.PhonyTarget(
|
||||||
|
"devboard_flash", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/wifi_board.py"]]
|
||||||
|
)
|
||||||
|
|
||||||
# Linter
|
# Linter
|
||||||
|
|
||||||
dist_env.PhonyTarget(
|
dist_env.PhonyTarget(
|
||||||
"lint",
|
"lint",
|
||||||
"${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}",
|
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "check", "${LINT_SOURCES}"]],
|
||||||
source=original_app_dir.File(".clang-format"),
|
source=original_app_dir.File(".clang-format"),
|
||||||
LINT_SOURCES=[original_app_dir],
|
LINT_SOURCES=[original_app_dir],
|
||||||
)
|
)
|
||||||
|
|
||||||
dist_env.PhonyTarget(
|
dist_env.PhonyTarget(
|
||||||
"format",
|
"format",
|
||||||
"${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}",
|
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "format", "${LINT_SOURCES}"]],
|
||||||
source=original_app_dir.File(".clang-format"),
|
source=original_app_dir.File(".clang-format"),
|
||||||
LINT_SOURCES=[original_app_dir],
|
LINT_SOURCES=[original_app_dir],
|
||||||
)
|
)
|
||||||
@ -455,7 +457,17 @@ if dolphin_src_dir.exists():
|
|||||||
)
|
)
|
||||||
dist_env.PhonyTarget(
|
dist_env.PhonyTarget(
|
||||||
"dolphin_ext",
|
"dolphin_ext",
|
||||||
'${PYTHON3} ${FBT_SCRIPT_DIR}/storage.py -p ${FLIP_PORT} send "${SOURCE}" /ext/dolphin',
|
[
|
||||||
|
[
|
||||||
|
"${PYTHON3}",
|
||||||
|
"${FBT_SCRIPT_DIR}/storage.py",
|
||||||
|
"-p",
|
||||||
|
"${FLIP_PORT}",
|
||||||
|
"send",
|
||||||
|
"${SOURCE}",
|
||||||
|
"/ext/dolphin",
|
||||||
|
]
|
||||||
|
],
|
||||||
source=ufbt_build_dir.Dir("dolphin"),
|
source=ufbt_build_dir.Dir("dolphin"),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -467,7 +479,7 @@ else:
|
|||||||
|
|
||||||
dist_env.PhonyTarget(
|
dist_env.PhonyTarget(
|
||||||
"env",
|
"env",
|
||||||
"@echo $( ${FBT_SCRIPT_DIR}/toolchain/fbtenv.sh $)",
|
"@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)",
|
||||||
)
|
)
|
||||||
|
|
||||||
dist_env.PostConfigureUfbtEnvionment()
|
dist_env.PostConfigureUfbtEnvionment()
|
||||||
|
@ -101,7 +101,7 @@ class Main(App):
|
|||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
self.parser_generate.add_argument(
|
self.parser_generate.add_argument(
|
||||||
"-fw-origin",
|
"--fw-origin",
|
||||||
dest="firmware_origin",
|
dest="firmware_origin",
|
||||||
type=str,
|
type=str,
|
||||||
help="firmware origin",
|
help="firmware origin",
|
||||||
|
@ -27,6 +27,8 @@ variables_to_forward = [
|
|||||||
"PYTHONNOUSERSITE",
|
"PYTHONNOUSERSITE",
|
||||||
"TMP",
|
"TMP",
|
||||||
"TEMP",
|
"TEMP",
|
||||||
|
# ccache
|
||||||
|
"CCACHE_DISABLE",
|
||||||
# Colors for tools
|
# Colors for tools
|
||||||
"TERM",
|
"TERM",
|
||||||
]
|
]
|
||||||
@ -62,7 +64,7 @@ coreenv = VAR_ENV.Clone(
|
|||||||
# Setting up temp file parameters - to overcome command line length limits
|
# Setting up temp file parameters - to overcome command line length limits
|
||||||
TEMPFILEARGESCFUNC=tempfile_arg_esc_func,
|
TEMPFILEARGESCFUNC=tempfile_arg_esc_func,
|
||||||
ROOT_DIR=Dir("#"),
|
ROOT_DIR=Dir("#"),
|
||||||
FBT_SCRIPT_DIR="${ROOT_DIR}/scripts",
|
FBT_SCRIPT_DIR=Dir("#/scripts"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# If DIST_SUFFIX is set in environment, is has precedence (set by CI)
|
# If DIST_SUFFIX is set in environment, is has precedence (set by CI)
|
||||||
|
Loading…
Reference in New Issue
Block a user