[FL-3162] Moved ufbt to fbt codebase (#2520)
* scripts: moved ufbt code * ufbt: fixed tool path * ufbt: fixed linter/formatter target descriptions * scripts: ufbt: cleanup * fbt: moved fap launch target to tools; ufbt fixes * fbt: fixed missing headers from SDK * ufbt: removed debug output * ufbt: moved project template to main codebase * ufbt: fixed vscode_dist * ufbt: path naming changes * fbt: error message for older ufbt versions * ufbt: docs fixes * ufbt: fixed build dir location * fbt: fixes for extapps objcopy * fbt: extapps: removed extra debug output; fixed formatting * ufbt: handle launch target for multiple known apps * ufbt: dropping wrapper; linter fixes * ufbt: fixed boostrap path * ufbt: renamed entrypoint * ufbt: updated vscode config * ufbt: moved sconsign db location * ufbt: fixed sconsign path * fbt: SDK builders rework * fbt: reworked sdk packaging * ufbt: additional checks and state processing * ufbt: fixed sdk state file location * dist: not packaging pycache * dump commit json content * Github: more workflow debug prints * Github: fix incorrect commit meta extraction in get_env.py * ufbt, fbt: changed SConsEnvironmentError->StopError * fbtenv: no longer needs SCRIPT_PATH pre-set * ufbt: fixed sdk state check * scripts: exception fixes for storage.py * scripts: fbtenv: added FBT_TOOLCHAIN_PATH for on Windows for compat * ufbt: app template: creating .gitkeep for images folder * ufbt: app template: fixed .gitkeep creation * docs: formatting fixes for AppManifests; added link to ufbt * fbt: added link to PyPI for old ufbt versions * sdk: fixed dir component paths Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
53
scripts/ufbt/site_tools/ufbt_help.py
Normal file
53
scripts/ufbt/site_tools/ufbt_help.py
Normal file
@@ -0,0 +1,53 @@
|
||||
targets_help = """Configuration variables:
|
||||
"""
|
||||
|
||||
tail_help = """
|
||||
|
||||
TASKS:
|
||||
(* - not supported yet)
|
||||
|
||||
launch:
|
||||
Upload and start application over USB
|
||||
vscode_dist:
|
||||
Configure application in current directory for development in VSCode.
|
||||
create:
|
||||
Copy application template to current directory. Set APPID=myapp to create an app with id 'myapp'.
|
||||
|
||||
Building:
|
||||
faps:
|
||||
Build all FAP apps
|
||||
fap_{APPID}, launch APPSRC={APPID}:
|
||||
Build FAP app with appid={APPID}; upload & start it over USB
|
||||
|
||||
Flashing & debugging:
|
||||
flash, flash_blackmagic, *jflash:
|
||||
Flash firmware to target using debug probe
|
||||
flash_usb, flash_usb_full:
|
||||
Install firmware using self-update package
|
||||
debug, debug_other, blackmagic:
|
||||
Start GDB
|
||||
|
||||
Other:
|
||||
cli:
|
||||
Open a Flipper CLI session over USB
|
||||
lint:
|
||||
run linter for C code
|
||||
format:
|
||||
reformat C code
|
||||
|
||||
How to create a new application:
|
||||
1. Create a new directory for your application and cd into it.
|
||||
2. Run `ufbt vscode_dist create APPID=myapp`
|
||||
3. In VSCode, open the folder and start editing.
|
||||
4. Run `ufbt launch` to build and upload your application.
|
||||
"""
|
||||
|
||||
|
||||
def generate(env, **kw):
|
||||
vars = kw["vars"]
|
||||
basic_help = vars.GenerateHelpText(env)
|
||||
env.Help(targets_help + basic_help + tail_help)
|
||||
|
||||
|
||||
def exists(env):
|
||||
return True
|
117
scripts/ufbt/site_tools/ufbt_state.py
Normal file
117
scripts/ufbt/site_tools/ufbt_state.py
Normal file
@@ -0,0 +1,117 @@
|
||||
from SCons.Errors import StopError
|
||||
from SCons.Warnings import warn, WarningOnByDefault
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import pathlib
|
||||
from functools import reduce
|
||||
|
||||
|
||||
def _load_sdk_data(sdk_root):
|
||||
split_vars = {
|
||||
"cc_args",
|
||||
"cpp_args",
|
||||
"linker_args",
|
||||
"linker_libs",
|
||||
}
|
||||
subst_vars = split_vars | {
|
||||
"sdk_symbols",
|
||||
}
|
||||
sdk_data = {}
|
||||
with open(os.path.join(sdk_root, "sdk.opts")) as f:
|
||||
sdk_json_data = json.load(f)
|
||||
replacements = {
|
||||
sdk_json_data["app_ep_subst"]: "${APP_ENTRY}",
|
||||
sdk_json_data["sdk_path_subst"]: sdk_root.replace("\\", "/"),
|
||||
sdk_json_data["map_file_subst"]: "${TARGET}",
|
||||
}
|
||||
|
||||
def do_value_substs(src_value):
|
||||
if isinstance(src_value, str):
|
||||
return reduce(
|
||||
lambda acc, kv: acc.replace(*kv), replacements.items(), src_value
|
||||
)
|
||||
elif isinstance(src_value, list):
|
||||
return [do_value_substs(v) for v in src_value]
|
||||
else:
|
||||
return src_value
|
||||
|
||||
for key, value in sdk_json_data.items():
|
||||
if key in split_vars:
|
||||
value = value.split()
|
||||
if key in subst_vars:
|
||||
value = do_value_substs(value)
|
||||
sdk_data[key] = value
|
||||
|
||||
return sdk_data
|
||||
|
||||
|
||||
def _load_state_file(state_dir_node, filename: str) -> dict:
|
||||
state_path = os.path.join(state_dir_node.abspath, filename)
|
||||
if not os.path.exists(state_path):
|
||||
raise StopError(f"State file {state_path} not found")
|
||||
|
||||
with open(state_path, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def generate(env, **kw):
|
||||
sdk_current_sdk_dir_node = env["UFBT_CURRENT_SDK_DIR"]
|
||||
|
||||
sdk_components_filename = kw.get("SDK_COMPONENTS", "components.json")
|
||||
ufbt_state_filename = kw.get("UFBT_STATE", "ufbt_state.json")
|
||||
|
||||
sdk_state = _load_state_file(sdk_current_sdk_dir_node, sdk_components_filename)
|
||||
ufbt_state = _load_state_file(sdk_current_sdk_dir_node, ufbt_state_filename)
|
||||
|
||||
if not (sdk_components := sdk_state.get("components", {})):
|
||||
raise StopError("SDK state file doesn't contain components data")
|
||||
|
||||
sdk_data = _load_sdk_data(
|
||||
sdk_current_sdk_dir_node.Dir(sdk_components["sdk_headers.dir"]).abspath
|
||||
)
|
||||
|
||||
if not sdk_state["meta"]["hw_target"].endswith(sdk_data["hardware"]):
|
||||
raise StopError("SDK state file doesn't match hardware target")
|
||||
|
||||
if sdk_state["meta"]["version"] != ufbt_state["version"]:
|
||||
warn(
|
||||
WarningOnByDefault,
|
||||
f"Version mismatch: SDK state vs uFBT: {sdk_state['meta']['version']} vs {ufbt_state['version']}",
|
||||
)
|
||||
|
||||
scripts_dir = sdk_current_sdk_dir_node.Dir(sdk_components["scripts.dir"])
|
||||
env.SetDefault(
|
||||
# Paths
|
||||
SDK_DEFINITION=env.File(sdk_data["sdk_symbols"]),
|
||||
FBT_DEBUG_DIR=pathlib.Path(
|
||||
sdk_current_sdk_dir_node.Dir(sdk_components["debug.dir"]).abspath
|
||||
).as_posix(),
|
||||
FBT_SCRIPT_DIR=scripts_dir,
|
||||
LIBPATH=sdk_current_sdk_dir_node.Dir(sdk_components["lib.dir"]),
|
||||
FW_ELF=sdk_current_sdk_dir_node.File(sdk_components["firmware.elf"]),
|
||||
FW_BIN=sdk_current_sdk_dir_node.File(sdk_components["full.bin"]),
|
||||
UPDATE_BUNDLE_DIR=sdk_current_sdk_dir_node.Dir(sdk_components["update.dir"]),
|
||||
SVD_FILE="${FBT_DEBUG_DIR}/STM32WB55_CM4.svd",
|
||||
# Build variables
|
||||
ROOT_DIR=env.Dir("#"),
|
||||
FIRMWARE_BUILD_CFG="firmware",
|
||||
TARGET_HW=int(sdk_data["hardware"]),
|
||||
CFLAGS_APP=sdk_data["cc_args"],
|
||||
CXXFLAGS_APP=sdk_data["cpp_args"],
|
||||
LINKFLAGS_APP=sdk_data["linker_args"],
|
||||
LIBS=sdk_data["linker_libs"],
|
||||
# ufbt state
|
||||
# UFBT_STATE_DIR=ufbt_state_dir_node,
|
||||
# UFBT_CURRENT_SDK_DIR=sdk_current_sdk_dir_node,
|
||||
UFBT_STATE=ufbt_state,
|
||||
UFBT_BOOTSTRAP_SCRIPT="${UFBT_SCRIPT_DIR}/bootstrap.py",
|
||||
UFBT_SCRIPT_ROOT=scripts_dir.Dir("ufbt"),
|
||||
)
|
||||
|
||||
sys.path.insert(0, env["FBT_SCRIPT_DIR"].abspath)
|
||||
|
||||
|
||||
def exists(env):
|
||||
return True
|
Reference in New Issue
Block a user