[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