unleashed-firmware/scripts/fbt_tools/fbt_resources.py
hedger bbe68d6ffc
[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
2023-10-31 15:27:58 +04:00

118 lines
3.5 KiB
Python

import os
import shutil
from SCons.Action import Action
from SCons.Builder import Builder
from SCons.Errors import StopError
from SCons.Node.FS import Dir, File
def __generate_resources_dist_entries(env):
src_target_entries = []
resources_root = env.Dir(env["RESOURCES_ROOT"])
for app_artifacts in env["FW_EXTAPPS"].application_map.values():
for _, dist_path in filter(
lambda dist_entry: dist_entry[0], app_artifacts.dist_entries
):
src_target_entries.append(
(
app_artifacts.compact,
resources_root.File(dist_path),
)
)
# Deploy apps' resources too
for app in env["APPBUILD"].apps:
if not app.resources:
continue
apps_resource_dir = app._appdir.Dir(app.resources)
for res_file in env.GlobRecursive("*", apps_resource_dir):
if not isinstance(res_file, File):
continue
src_target_entries.append(
(
res_file,
resources_root.File(
res_file.get_path(apps_resource_dir),
),
)
)
# Deploy other stuff from _EXTRA_DIST
for extra_dist in env["_EXTRA_DIST"]:
if isinstance(extra_dist, Dir):
src_target_entries.append(
(
extra_dist,
resources_root.Dir(extra_dist.name),
)
)
else:
raise StopError(f"Unsupported extra dist type: {type(extra_dist)}")
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)
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)
for src, target in dist_entries:
if isinstance(src, File):
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):
env.SetDefault(
ASSETS_COMPILER="${FBT_SCRIPT_DIR}/assets.py",
)
if not env["VERBOSE"]:
env.SetDefault(
RESOURCEDISTCOMSTR="\tRESDIST\t${RESOURCES_ROOT}",
RESMANIFESTCOMSTR="\tMANIFST\t${TARGET}",
)
env.Append(
BUILDERS={
"ManifestBuilder": Builder(
action=[
Action(
_resources_dist_action,
"${RESOURCEDISTCOMSTR}",
),
Action(
[
[
"${PYTHON3}",
"${ASSETS_COMPILER}",
"manifest",
"${TARGET.dir.posix}",
"--timestamp=${GIT_UNIX_TIMESTAMP}",
]
],
"${RESMANIFESTCOMSTR}",
),
],
emitter=_resources_dist_emitter,
),
}
)
def exists(env):
return True