unleashed-firmware/scripts/ufbt/site_tools/ufbt_state.py
hedger a91d319839
[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>
2023-04-06 10:44:37 +08:00

118 lines
4.0 KiB
Python

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