[FL-3629] fbt: SD card resource handling speedup (#3178)
* fbt: reduced size of resources dependency graphs, resulting in faster build task evaluation * lib: flipper_app: fixed error message & error handling for plugins
This commit is contained in:
parent
9af81ce8d0
commit
bbe68d6ffc
@ -148,15 +148,11 @@ if env["IS_BASE_FIRMWARE"]:
|
|||||||
)
|
)
|
||||||
fw_artifacts.append(fw_extapps.sdk_tree)
|
fw_artifacts.append(fw_extapps.sdk_tree)
|
||||||
|
|
||||||
# Resources for SD card
|
# Resources & manifest for SD card
|
||||||
resources = fwenv.ResourcesDist(
|
|
||||||
_EXTRA_DIST=[fwenv["DOLPHIN_EXTERNAL_OUT_DIR"]],
|
|
||||||
)
|
|
||||||
|
|
||||||
manifest = fwenv.ManifestBuilder(
|
manifest = fwenv.ManifestBuilder(
|
||||||
"${RESOURCES_ROOT}/Manifest",
|
"${RESOURCES_ROOT}/Manifest",
|
||||||
source=resources,
|
|
||||||
GIT_UNIX_TIMESTAMP=get_git_commit_unix_timestamp(),
|
GIT_UNIX_TIMESTAMP=get_git_commit_unix_timestamp(),
|
||||||
|
_EXTRA_DIST=[fwenv["DOLPHIN_EXTERNAL_OUT_DIR"]],
|
||||||
)
|
)
|
||||||
fwenv.Replace(FW_RESOURCES_MANIFEST=manifest)
|
fwenv.Replace(FW_RESOURCES_MANIFEST=manifest)
|
||||||
fwenv.Alias("resources", manifest)
|
fwenv.Alias("resources", manifest)
|
||||||
|
|||||||
@ -66,7 +66,8 @@ PluginManagerError plugin_manager_load_single(PluginManager* manager, const char
|
|||||||
|
|
||||||
FlipperApplicationLoadStatus load_status = flipper_application_map_to_memory(lib);
|
FlipperApplicationLoadStatus load_status = flipper_application_map_to_memory(lib);
|
||||||
if(load_status != FlipperApplicationLoadStatusSuccess) {
|
if(load_status != FlipperApplicationLoadStatusSuccess) {
|
||||||
FURI_LOG_E(TAG, "Failed to load module_demo_plugin1.fal");
|
FURI_LOG_E(TAG, "Failed to load %s", path);
|
||||||
|
error = PluginManagerErrorLoaderError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,24 +30,26 @@ def _proto_emitter(target, source, env):
|
|||||||
|
|
||||||
def _dolphin_emitter(target, source, env):
|
def _dolphin_emitter(target, source, env):
|
||||||
res_root_dir = source[0].Dir(env["DOLPHIN_RES_TYPE"])
|
res_root_dir = source[0].Dir(env["DOLPHIN_RES_TYPE"])
|
||||||
source = [res_root_dir]
|
source = list()
|
||||||
source.extend(env.GlobRecursive("*.*", res_root_dir.srcnode()))
|
source.extend(env.GlobRecursive("*.*", res_root_dir.srcnode()))
|
||||||
|
|
||||||
target_base_dir = target[0]
|
target_base_dir = target[0]
|
||||||
env.Replace(_DOLPHIN_OUT_DIR=target[0])
|
env.Replace(_DOLPHIN_OUT_DIR=target[0])
|
||||||
|
env.Replace(_DOLPHIN_SRC_DIR=res_root_dir)
|
||||||
|
|
||||||
if env["DOLPHIN_RES_TYPE"] == "external":
|
if env["DOLPHIN_RES_TYPE"] == "external":
|
||||||
target = [target_base_dir.File("manifest.txt")]
|
target = [target_base_dir.File("manifest.txt")]
|
||||||
## A detailed list of files to be generated
|
## A detailed list of files to be generated
|
||||||
|
# Not used ATM, becasuse it inflates the internal dependency graph too much
|
||||||
# Preserve original paths, do .png -> .bm conversion
|
# Preserve original paths, do .png -> .bm conversion
|
||||||
target.extend(
|
# target.extend(
|
||||||
map(
|
# map(
|
||||||
lambda node: target_base_dir.File(
|
# lambda node: target_base_dir.File(
|
||||||
res_root_dir.rel_path(node).replace(".png", ".bm")
|
# res_root_dir.rel_path(node).replace(".png", ".bm")
|
||||||
),
|
# ),
|
||||||
filter(lambda node: isinstance(node, File), source),
|
# filter(lambda node: isinstance(node, File), source),
|
||||||
)
|
# )
|
||||||
)
|
# )
|
||||||
else:
|
else:
|
||||||
asset_basename = f"assets_dolphin_{env['DOLPHIN_RES_TYPE']}"
|
asset_basename = f"assets_dolphin_{env['DOLPHIN_RES_TYPE']}"
|
||||||
target = [
|
target = [
|
||||||
@ -55,7 +57,7 @@ def _dolphin_emitter(target, source, env):
|
|||||||
target_base_dir.File(asset_basename + ".h"),
|
target_base_dir.File(asset_basename + ".h"),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Debug output
|
## Debug output
|
||||||
# print(
|
# print(
|
||||||
# f"Dolphin res type: {env['DOLPHIN_RES_TYPE']},\ntarget files:",
|
# f"Dolphin res type: {env['DOLPHIN_RES_TYPE']},\ntarget files:",
|
||||||
# list(f.path for f in target),
|
# list(f.path for f in target),
|
||||||
@ -176,7 +178,7 @@ def generate(env):
|
|||||||
"dolphin",
|
"dolphin",
|
||||||
"-s",
|
"-s",
|
||||||
"dolphin_${DOLPHIN_RES_TYPE}",
|
"dolphin_${DOLPHIN_RES_TYPE}",
|
||||||
"${SOURCE}",
|
"${_DOLPHIN_SRC_DIR}",
|
||||||
"${_DOLPHIN_OUT_DIR}",
|
"${_DOLPHIN_OUT_DIR}",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -191,7 +193,7 @@ def generate(env):
|
|||||||
"${PYTHON3}",
|
"${PYTHON3}",
|
||||||
"${ASSETS_COMPILER}",
|
"${ASSETS_COMPILER}",
|
||||||
"dolphin",
|
"dolphin",
|
||||||
"${SOURCE}",
|
"${_DOLPHIN_SRC_DIR}",
|
||||||
"${_DOLPHIN_OUT_DIR}",
|
"${_DOLPHIN_OUT_DIR}",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
@ -7,16 +7,21 @@ from SCons.Errors import StopError
|
|||||||
from SCons.Node.FS import Dir, File
|
from SCons.Node.FS import Dir, File
|
||||||
|
|
||||||
|
|
||||||
def _resources_dist_emitter(target, source, env):
|
def __generate_resources_dist_entries(env):
|
||||||
|
src_target_entries = []
|
||||||
|
|
||||||
resources_root = env.Dir(env["RESOURCES_ROOT"])
|
resources_root = env.Dir(env["RESOURCES_ROOT"])
|
||||||
|
|
||||||
target = []
|
|
||||||
for app_artifacts in env["FW_EXTAPPS"].application_map.values():
|
for app_artifacts in env["FW_EXTAPPS"].application_map.values():
|
||||||
for _, dist_path in filter(
|
for _, dist_path in filter(
|
||||||
lambda dist_entry: dist_entry[0], app_artifacts.dist_entries
|
lambda dist_entry: dist_entry[0], app_artifacts.dist_entries
|
||||||
):
|
):
|
||||||
source.append(app_artifacts.compact)
|
src_target_entries.append(
|
||||||
target.append(resources_root.File(dist_path))
|
(
|
||||||
|
app_artifacts.compact,
|
||||||
|
resources_root.File(dist_path),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Deploy apps' resources too
|
# Deploy apps' resources too
|
||||||
for app in env["APPBUILD"].apps:
|
for app in env["APPBUILD"].apps:
|
||||||
@ -26,34 +31,48 @@ def _resources_dist_emitter(target, source, env):
|
|||||||
for res_file in env.GlobRecursive("*", apps_resource_dir):
|
for res_file in env.GlobRecursive("*", apps_resource_dir):
|
||||||
if not isinstance(res_file, File):
|
if not isinstance(res_file, File):
|
||||||
continue
|
continue
|
||||||
source.append(res_file)
|
src_target_entries.append(
|
||||||
target.append(resources_root.File(res_file.get_path(apps_resource_dir)))
|
(
|
||||||
|
res_file,
|
||||||
|
resources_root.File(
|
||||||
|
res_file.get_path(apps_resource_dir),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Deploy other stuff from _EXTRA_DIST
|
# Deploy other stuff from _EXTRA_DIST
|
||||||
for extra_dist in env["_EXTRA_DIST"]:
|
for extra_dist in env["_EXTRA_DIST"]:
|
||||||
if isinstance(extra_dist, Dir):
|
if isinstance(extra_dist, Dir):
|
||||||
for extra_file in env.GlobRecursive("*", extra_dist):
|
src_target_entries.append(
|
||||||
if not isinstance(extra_file, File):
|
(
|
||||||
continue
|
extra_dist,
|
||||||
source.append(extra_file)
|
resources_root.Dir(extra_dist.name),
|
||||||
target.append(
|
|
||||||
# Preserve dir name from original node
|
|
||||||
resources_root.Dir(extra_dist.name).File(
|
|
||||||
extra_file.get_path(extra_dist)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise StopError(f"Unsupported extra dist type: {type(extra_dist)}")
|
raise StopError(f"Unsupported extra dist type: {type(extra_dist)}")
|
||||||
|
|
||||||
assert len(target) == len(source)
|
return src_target_entries
|
||||||
|
|
||||||
|
|
||||||
|
def _resources_dist_emitter(target, source, env):
|
||||||
|
src_target_entries = __generate_resources_dist_entries(env)
|
||||||
|
source = list(map(lambda entry: entry[0], src_target_entries))
|
||||||
return (target, source)
|
return (target, source)
|
||||||
|
|
||||||
|
|
||||||
def _resources_dist_action(target, source, env):
|
def _resources_dist_action(target, source, env):
|
||||||
|
dist_entries = __generate_resources_dist_entries(env)
|
||||||
|
assert len(dist_entries) == len(source)
|
||||||
shutil.rmtree(env.Dir(env["RESOURCES_ROOT"]).abspath, ignore_errors=True)
|
shutil.rmtree(env.Dir(env["RESOURCES_ROOT"]).abspath, ignore_errors=True)
|
||||||
for src, target in zip(source, target):
|
for src, target in dist_entries:
|
||||||
os.makedirs(os.path.dirname(target.path), exist_ok=True)
|
if isinstance(src, File):
|
||||||
shutil.copy(src.path, target.path)
|
os.makedirs(os.path.dirname(target.path), exist_ok=True)
|
||||||
|
shutil.copy(src.path, target.path)
|
||||||
|
elif isinstance(src, Dir):
|
||||||
|
shutil.copytree(src.path, target.path)
|
||||||
|
else:
|
||||||
|
raise StopError(f"Unsupported dist entry type: {type(src)}")
|
||||||
|
|
||||||
|
|
||||||
def generate(env, **kw):
|
def generate(env, **kw):
|
||||||
@ -69,26 +88,26 @@ def generate(env, **kw):
|
|||||||
|
|
||||||
env.Append(
|
env.Append(
|
||||||
BUILDERS={
|
BUILDERS={
|
||||||
"ResourcesDist": Builder(
|
|
||||||
action=Action(
|
|
||||||
_resources_dist_action,
|
|
||||||
"${RESOURCEDISTCOMSTR}",
|
|
||||||
),
|
|
||||||
emitter=_resources_dist_emitter,
|
|
||||||
),
|
|
||||||
"ManifestBuilder": Builder(
|
"ManifestBuilder": Builder(
|
||||||
action=Action(
|
action=[
|
||||||
[
|
Action(
|
||||||
|
_resources_dist_action,
|
||||||
|
"${RESOURCEDISTCOMSTR}",
|
||||||
|
),
|
||||||
|
Action(
|
||||||
[
|
[
|
||||||
"${PYTHON3}",
|
[
|
||||||
"${ASSETS_COMPILER}",
|
"${PYTHON3}",
|
||||||
"manifest",
|
"${ASSETS_COMPILER}",
|
||||||
"${TARGET.dir.posix}",
|
"manifest",
|
||||||
"--timestamp=${GIT_UNIX_TIMESTAMP}",
|
"${TARGET.dir.posix}",
|
||||||
]
|
"--timestamp=${GIT_UNIX_TIMESTAMP}",
|
||||||
],
|
]
|
||||||
"${RESMANIFESTCOMSTR}",
|
],
|
||||||
)
|
"${RESMANIFESTCOMSTR}",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
emitter=_resources_dist_emitter,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user