diff --git a/build/toolchain/android/android_toolchain.gni b/build/toolchain/android/android_toolchain.gni index e4eed1b30b577e..f1242b6cbcd855 100644 --- a/build/toolchain/android/android_toolchain.gni +++ b/build/toolchain/android/android_toolchain.gni @@ -69,6 +69,5 @@ template("android_clang_toolchain") { ar = _ndk_prefix + "llvm-ar" cc = _ndk_prefix + _tool_name_root + "clang" cxx = _ndk_prefix + _tool_name_root + "clang++" - link_generate_map_file = false } } diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index b4b39daf711fb0..dce52ec7644df8 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni @@ -16,11 +16,9 @@ import("//build_overrides/pigweed.gni") import("$dir_pw_toolchain/generate_toolchain.gni") declare_args() { - # Generate Linker map files. Can skip since they can + # Generate Linker map files. By default it is disabled since they can # be quite large. - # - # Note that toolchains can individually override this - chip_generate_link_map_file = true + chip_generate_link_map_file = false } template("gcc_toolchain") { @@ -48,11 +46,7 @@ template("gcc_toolchain") { cxx = invoker.cxx } - if (defined(invoker.link_generate_map_file)) { - link_generate_map_file = invoker.link_generate_map_file - } else { - link_generate_map_file = chip_generate_link_map_file - } + link_generate_map_file = chip_generate_link_map_file is_host_toolchain = invoker_toolchain_args.current_os == host_os link_group = invoker_toolchain_args.current_os != "mac" && diff --git a/examples/chef/chef.py b/examples/chef/chef.py index d3b9fae0ec06ff..6176c6e8c280ac 100755 --- a/examples/chef/chef.py +++ b/examples/chef/chef.py @@ -811,6 +811,7 @@ def main() -> int: 'chip_shell_cmd_server = false', 'chip_build_libshell = true', 'chip_enable_openthread = false', + 'chip_generate_link_map_file = true', 'chip_config_network_layer_ble = false', 'chip_device_project_config_include = ""', 'chip_project_config_include = ""', diff --git a/scripts/build/build_examples.py b/scripts/build/build_examples.py index a52c9aa6f3e131..e1f37fca797d7f 100755 --- a/scripts/build/build_examples.py +++ b/scripts/build/build_examples.py @@ -83,14 +83,17 @@ def ValidateTargetNames(context, parameter, values): default=[], multiple=True, callback=ValidateTargetNames, - help='Build target(s)' -) + help='Build target(s)') +@click.option( + '--enable-link-map-file', + default=False, + is_flag=True, + help='Enable generation of link map files.') @click.option( '--enable-flashbundle', default=False, is_flag=True, - help='Also generate the flashbundles for the app.' -) + help='Also generate the flashbundles for the app.') @click.option( '--repo', default='.', @@ -132,7 +135,7 @@ def ValidateTargetNames(context, parameter, values): 'Set pigweed command launcher. E.g.: "--pw-command-launcher=ccache" ' 'for using ccache when building examples.')) @click.pass_context -def main(context, log_level, target, repo, +def main(context, log_level, target, enable_link_map_file, repo, out_prefix, pregen_dir, clean, dry_run, dry_run_output, enable_flashbundle, no_log_timestamps, pw_command_launcher): # Ensures somewhat pretty logging of what is going on @@ -160,6 +163,7 @@ def main(context, log_level, target, repo, context.obj = build.Context( repository_path=repo, output_prefix=out_prefix, runner=runner) context.obj.SetupBuilders(targets=requested_targets, options=BuilderOptions( + enable_link_map_file=enable_link_map_file, enable_flashbundle=enable_flashbundle, pw_command_launcher=pw_command_launcher, pregen_dir=pregen_dir, diff --git a/scripts/build/builders/ameba.py b/scripts/build/builders/ameba.py index 677b47bbd43a01..802ce1f73cbe62 100644 --- a/scripts/build/builders/ameba.py +++ b/scripts/build/builders/ameba.py @@ -15,7 +15,7 @@ import os from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class AmebaBoard(Enum): @@ -89,18 +89,19 @@ def _build(self): title='Building ' + self.identifier) def build_outputs(self): - return { - self.app.AppNamePrefix + '.axf': - os.path.join(self.output_dir, 'asdk', 'target_image2.axf'), - self.app.AppNamePrefix + '.map': + yield BuilderOutput( + os.path.join(self.output_dir, 'asdk', 'target_image2.axf'), + self.app.AppNamePrefix + '.axf') + if self.options.enable_link_map_file: + yield BuilderOutput( os.path.join(self.output_dir, 'asdk', 'target_image2.map'), - 'km0_boot_all.bin': - os.path.join(self.output_dir, 'asdk', - 'bootloader', 'km0_boot_all.bin'), - 'km4_boot_all.bin': - os.path.join(self.output_dir, 'asdk', - 'bootloader', 'km4_boot_all.bin'), - 'km0_km4_image2.bin': - os.path.join(self.output_dir, 'asdk', - 'image', 'km0_km4_image2.bin'), - } + self.app.AppNamePrefix + '.map') + yield BuilderOutput( + os.path.join(self.output_dir, 'asdk', 'bootloader', 'km0_boot_all.bin'), + 'km0_boot_all.bin') + yield BuilderOutput( + os.path.join(self.output_dir, 'asdk', 'bootloader', 'km4_boot_all.bin'), + 'km4_boot_all.bin') + yield BuilderOutput( + os.path.join(self.output_dir, 'asdk', 'image', 'km0_km4_image2.bin'), + 'km0_km4_image2.bin') diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index bd2c90c28136d6..94d3a566a63877 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -16,7 +16,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class AndroidBoard(Enum): @@ -366,6 +366,9 @@ def generate(self): if self.options.pw_command_launcher: gn_args["pw_command_launcher"] = self.options.pw_command_launcher + if self.options.enable_link_map_file: + gn_args["chip_generate_link_map_file"] = True + if exampleName == "chip-test": gn_args["chip_build_tests"] = True if self.profile != AndroidProfile.DEBUG: @@ -569,85 +572,61 @@ def _build(self): def build_outputs(self): if self.board.IsIde(): - outputs = { - self.app.AppName() - + "-debug.apk": os.path.join( + yield BuilderOutput( + os.path.join( self.root, "examples/android", self.app.AppName(), - "app/build/outputs/apk/debug/app-debug.apk", - ) - } + "app/build/outputs/apk/debug/app-debug.apk"), + self.app.AppName() + "-debug.apk") elif self.app.ExampleName() is not None: if self.app == AndroidApp.TV_SERVER: - outputs = { - "tv-sever-platform-app-debug.apk": os.path.join( - self.output_dir, "platform-app", "outputs", "apk", "debug", "platform-app-debug.apk" - ), - "tv-sever-content-app-debug.apk": os.path.join( - self.output_dir, "content-app", "outputs", "apk", "debug", "content-app-debug.apk" - ) - } + yield BuilderOutput( + os.path.join(self.output_dir, "platform-app", + "outputs", "apk", "debug", "platform-app-debug.apk"), + "tv-sever-platform-app-debug.apk") + yield BuilderOutput( + os.path.join(self.output_dir, "content-app", + "outputs", "apk", "debug", "content-app-debug.apk"), + "tv-sever-content-app-debug.apk") elif self.app == AndroidApp.VIRTUAL_DEVICE_APP: - outputs = { - self.app.AppName() + "app-debug.apk": os.path.join( - self.output_dir, "VirtualDeviceApp", "app", "outputs", "apk", "debug", "app-debug.apk" - ) - } + yield BuilderOutput( + os.path.join(self.output_dir, "VirtualDeviceApp", "app", + "outputs", "apk", "debug", "app-debug.apk"), + self.app.AppName() + "app-debug.apk") else: - outputs = { - self.app.AppName() + "app-debug.apk": os.path.join( - self.output_dir, "outputs", "apk", "debug", "app-debug.apk" - ) - } + yield BuilderOutput( + os.path.join(self.output_dir, + "outputs", "apk", "debug", "app-debug.apk"), + self.app.AppName() + "app-debug.apk") else: - outputs = { - self.app.AppName() + "app-debug.apk": os.path.join( - self.output_dir, "outputs", "apk", "debug", "app-debug.apk" - ), - "CHIPController.jar": os.path.join( - self.output_dir, "lib", "src/controller/java/CHIPController.jar" - ), - "CHIPInteractionModel.jar": os.path.join( - self.output_dir, "lib", "src/controller/java/CHIPInteractionModel.jar" - ), - "libMatterTlv.jar": os.path.join( - self.output_dir, "lib", "src/controller/java/libMatterTlv.jar" - ), - "AndroidPlatform.jar": os.path.join( - self.output_dir, "lib", "src/platform/android/AndroidPlatform.jar" - ), - "OnboardingPayload.jar": os.path.join( - self.output_dir, - "lib", - "src/controller/java/OnboardingPayload.jar", - ), - "CHIPClusters.jar": os.path.join( - self.output_dir, - "lib", - "src/controller/java/CHIPClusters.jar", - ), - "CHIPClusterID.jar": os.path.join( - self.output_dir, - "lib", - "src/controller/java/CHIPClusterID.jar", - ), - "jni/%s/libCHIPController.so" - % self.board.AbiName(): os.path.join( - self.output_dir, - "lib", - "jni", - self.board.AbiName(), - "libCHIPController.so", - ), - "jni/%s/libc++_shared.so" - % self.board.AbiName(): os.path.join( - self.output_dir, - "lib", - "jni", - self.board.AbiName(), - "libc++_shared.so", - ), - } - - return outputs + yield BuilderOutput( + os.path.join(self.output_dir, "outputs", "apk", "debug", "app-debug.apk"), + self.app.AppName() + "app-debug.apk") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "CHIPController.jar"), + "CHIPController.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "CHIPInteractionModel.jar"), + "CHIPInteractionModel.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "libMatterTlv.jar"), + "libMatterTlv.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "platform", "android", "AndroidPlatform.jar"), + "AndroidPlatform.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "OnboardingPayload.jar"), + "OnboardingPayload.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "CHIPClusters.jar"), + "CHIPClusters.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "CHIPClusterID.jar"), + "CHIPClusterID.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "jni", self.board.AbiName(), "libCHIPController.so"), + "jni/%s/libCHIPController.so" % self.board.AbiName()) + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "jni", self.board.AbiName(), "libc++_shared.so"), + "jni/%s/libc++_shared.so" % self.board.AbiName()) diff --git a/scripts/build/builders/asr.py b/scripts/build/builders/asr.py index d7351a1daec289..a901147cf1e7a7 100644 --- a/scripts/build/builders/asr.py +++ b/scripts/build/builders/asr.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -178,13 +179,9 @@ def GnBuildArgs(self): return self.extra_gn_options def build_outputs(self): - items = { - '%s.out' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix()), - '%s.out.map' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix()), - } - - return items + extensions = ["out"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/bouffalolab.py b/scripts/build/builders/bouffalolab.py index 1b661bff045c07..a8adfbb2a32b74 100644 --- a/scripts/build/builders/bouffalolab.py +++ b/scripts/build/builders/bouffalolab.py @@ -16,6 +16,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -226,16 +227,12 @@ def GnBuildArgs(self): return self.argsOpt def build_outputs(self): - items = { - '%s.out' % self.app.AppNamePrefix(self.chip_name): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix(self.chip_name)), - '%s.out.map' % self.app.AppNamePrefix(self.chip_name): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix(self.chip_name)), - } - - return items + extensions = ["out"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix(self.chip_name)}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) def PostBuildCommand(self): diff --git a/scripts/build/builders/builder.py b/scripts/build/builders/builder.py index dc420fce5e6b41..2895300e12388e 100644 --- a/scripts/build/builders/builder.py +++ b/scripts/build/builders/builder.py @@ -22,6 +22,9 @@ @dataclass class BuilderOptions: + # Generate a link map file + enable_link_map_file: bool = False + # Enable flashbundle generation stage enable_flashbundle: bool = False @@ -32,6 +35,12 @@ class BuilderOptions: pregen_dir: str = None +@dataclass +class BuilderOutput: + source: str # Source file generated by the build + target: str # Target file to be copied to + + class Builder(ABC): """Generic builder base class for CHIP. @@ -59,63 +68,61 @@ def _build(self): """Perform an actual build""" raise NotImplementedError() - def _generate_flashbundle(self): - """Perform an actual generating of flashbundle + def _bundle(self): + """Perform an actual generating of flashbundle. - May do nothing (and builder can choose not to implement this) if the - app does not need special steps for generating flashbundle. (e.g. the - example apps on Linux platform can run the ELF files directly.) + May do nothing (and builder can choose not to implement this) if + the app does not need special steps for generating flashbundle (e.g. + on Linux platform, the output ELF files can be used directly). """ pass @abstractmethod def build_outputs(self): - """Return a list of relevant output files after a build. + """Return a list of relevant BuilderOutput objects after a build. - May use build output data (e.g. manifests), so this should be invoked - only after a build has succeeded. + May use build output data (e.g. manifests), so this should be + invoked only after a build has succeeded. """ raise NotImplementedError() - def flashbundle(self): - """Return the files in flashbundle. + def bundle_outputs(self): + """Return the BuilderOutput objects in flashbundle. - Return an empty dict (and builder can choose not to implement this) if the - app does not need special files as flashbundle. (e.g. the example apps on - Linux platform can run the ELF files directly.) + Return an empty list (and builder can choose not to implement this) + if the app does not need special files as flashbundle. - May use data from do_generate_flashbundle, so this should be invoked only - after do_generate_flashbundle has succeeded. + May use data from _bundle(), so this should be invoked only after + _bundle() has succeeded. """ - return {} + return [] def outputs(self): - artifacts = self.build_outputs() + outputs = list(self.build_outputs()) if self.options.enable_flashbundle: - artifacts.update(self.flashbundle()) - return artifacts + outputs.extend(self.bundle_outputs()) + return outputs def build(self): self._build() if self.options.enable_flashbundle: - self._generate_flashbundle() + self._bundle() def _Execute(self, cmdarray, title=None): self._runner.Run(cmdarray, title=title) def CompressArtifacts(self, target_file: str): with tarfile.open(target_file, "w:gz") as tar: - for target_name, source_name in self.outputs().items(): - logging.info( - f'Adding {source_name} into {target_file}/{target_name}') - tar.add(source_name, target_name) + for output in self.outputs(): + logging.info('Adding %s into %s(%s)', + output.source, target_file, output.target) + tar.add(output.source, output.target) def CopyArtifacts(self, target_dir: str): - for target_name, source_name in self.outputs().items(): - target_full_name = os.path.join(target_dir, target_name) - - logging.info('Copying %s into %s', source_name, target_name) + for output in self.outputs(): + logging.info(f'Copying {output.source} into {output.target}') + target_full_name = os.path.join(target_dir, output.target) target_dir_full_name = os.path.dirname(target_full_name) if not os.path.exists(target_dir_full_name): @@ -123,5 +130,5 @@ def CopyArtifacts(self, target_dir: str): target_dir_full_name) os.makedirs(target_dir_full_name) - shutil.copyfile(source_name, target_full_name) - shutil.copymode(source_name, target_full_name) + shutil.copyfile(output.source, target_full_name) + shutil.copymode(output.source, target_full_name) diff --git a/scripts/build/builders/cc32xx.py b/scripts/build/builders/cc32xx.py index f54b7531eecc81..2563cab948ce0b 100644 --- a/scripts/build/builders/cc32xx.py +++ b/scripts/build/builders/cc32xx.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -62,17 +63,14 @@ def GnBuildArgs(self): return args def build_outputs(self): - items = {} if (self.app == cc32xxApp.LOCK): - extensions = [".out", ".bin", ".out.map"] + extensions = ["out", "bin"] elif (self.app == cc32xxApp.AIR_PURIFIER): - extensions = [".out", ".bin", ".out.map"] - + extensions = ["out", "bin"] else: raise Exception('Unknown app type: %r' % self.app) - - for extension in extensions: - name = '%s%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) - - return items + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/cyw30739.py b/scripts/build/builders/cyw30739.py index 4c03edca3151ef..243c78bc524b82 100644 --- a/scripts/build/builders/cyw30739.py +++ b/scripts/build/builders/cyw30739.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -102,8 +103,9 @@ def GnBuildArgs(self): return args def build_outputs(self): - items = {} - for extension in ["elf", "elf.map"]: - name = "%s-%s.%s" % (self.app.AppNamePrefix(), self.board.GnArgName(), extension) - items[name] = os.path.join(self.output_dir, name) - return items + extensions = ["elf"] + if self.options.enable_link_map_file: + extensions.append("elf.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}-{self.board.GnArgName()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/efr32.py b/scripts/build/builders/efr32.py index 1144cfc8c54a16..b0ad37be4774a9 100644 --- a/scripts/build/builders/efr32.py +++ b/scripts/build/builders/efr32.py @@ -17,6 +17,7 @@ import subprocess from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -263,26 +264,27 @@ def GnBuildArgs(self): return self.extra_gn_options def build_outputs(self): - items = {} - for extension in ["out", "out.map", "hex"]: - name = '%s.%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) + extensions = ["out", "hex"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) if self.app == Efr32App.UNIT_TEST: # Include test runner python wheels for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_nl_test_runner_wheels')): for file in files: - items["chip_nl_test_runner_wheels/" + - file] = os.path.join(root, file) + yield BuilderOutput( + os.path.join(root, file), + os.path.join("chip_nl_test_runner_wheels", file)) # Figure out flash bundle files and build accordingly with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: - for line in f.readlines(): - name = line.strip() - items['flashbundle/%s' % - name] = os.path.join(self.output_dir, name) - - return items + for name in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput( + os.path.join(self.output_dir, name), + os.path.join("flashbundle", name)) def generate(self): cmd = [ @@ -298,6 +300,9 @@ def generate(self): if self.options.pw_command_launcher: extra_args.append('pw_command_launcher="%s"' % self.options.pw_command_launcher) + if self.options.enable_link_map_file: + extra_args.append('chip_generate_link_map_file=true') + if self.options.pregen_dir: extra_args.append('chip_code_pre_generated_directory="%s"' % self.options.pregen_dir) diff --git a/scripts/build/builders/esp32.py b/scripts/build/builders/esp32.py index 468a92072c9fd9..3528a5873050e4 100644 --- a/scripts/build/builders/esp32.py +++ b/scripts/build/builders/esp32.py @@ -17,7 +17,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class Esp32Board(Enum): @@ -248,26 +248,21 @@ def _build(self): def build_outputs(self): if self.app == Esp32App.TESTS: # Include the runnable image names as artifacts - result = dict() with open(os.path.join(self.output_dir, 'test_images.txt'), 'rt') as f: - for name in f.readlines(): - name = name.strip() - result[name] = os.path.join(self.output_dir, name) - - return result + for name in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput(os.path.join(self.output_dir, name), name) + return - return { - self.app.AppNamePrefix + '.elf': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.elf'), - self.app.AppNamePrefix + '.map': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.map'), - } + extensions = ["elf"] + if self.options.enable_link_map_file: + extensions.append("map") + for ext in extensions: + name = f"{self.app.AppNamePrefix}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) - def flashbundle(self): + def bundle_outputs(self): if not self.app.FlashBundleName: - return {} - - with open(os.path.join(self.output_dir, self.app.FlashBundleName), 'r') as fp: - return { - line.strip(): os.path.join(self.output_dir, line.strip()) for line in fp.readlines() if line.strip() - } + return + with open(os.path.join(self.output_dir, self.app.FlashBundleName)) as f: + for line in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput(os.path.join(self.output_dir, line), line) diff --git a/scripts/build/builders/genio.py b/scripts/build/builders/genio.py index 822f198fd798da..ed7a8518f7d128 100755 --- a/scripts/build/builders/genio.py +++ b/scripts/build/builders/genio.py @@ -1,6 +1,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -48,9 +49,9 @@ def __init__(self, self.app = app def build_outputs(self): - items = {} - for extension in ['out', 'out.map', 'bin']: - name = '%s.%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) - - return items + extensions = ['out', 'bin'] + if self.options.enable_link_map_file: + extensions.append('out.map') + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/gn.py b/scripts/build/builders/gn.py index 75f6bb02c4231e..d2b09f393c1597 100644 --- a/scripts/build/builders/gn.py +++ b/scripts/build/builders/gn.py @@ -64,6 +64,9 @@ def generate(self): if self.options.pw_command_launcher: extra_args.append('pw_command_launcher="%s"' % self.options.pw_command_launcher) + if self.options.enable_link_map_file: + extra_args.append('chip_generate_link_map_file=true') + if self.options.pregen_dir: extra_args.append('chip_code_pre_generated_directory="%s"' % self.options.pregen_dir) diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 667cd39d47da99..822375fdd65c05 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -17,6 +17,7 @@ from platform import uname from typing import Optional +from .builder import BuilderOutput from .gn import GnBuilder @@ -564,19 +565,13 @@ def PostBuildCommand(self): self.createJavaExecutable("kotlin-matter-controller") def build_outputs(self): - outputs = {} - for name in self.app.OutputNames(): + if not self.options.enable_link_map_file and name.endswith(".map"): + continue path = os.path.join(self.output_dir, name) if os.path.isdir(path): for root, dirs, files in os.walk(path): for file in files: - outputs.update({ - file: os.path.join(root, file) - }) + yield BuilderOutput(os.path.join(root, file), file) else: - outputs.update({ - name: os.path.join(self.output_dir, name) - }) - - return outputs + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/imx.py b/scripts/build/builders/imx.py index e748144edc21a1..0d10557b8c5396 100644 --- a/scripts/build/builders/imx.py +++ b/scripts/build/builders/imx.py @@ -17,6 +17,7 @@ import shlex from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -180,19 +181,13 @@ def SysRootPath(self, name): return os.environ[name] def build_outputs(self): - outputs = {} - for name in self.app.OutputNames(): + if not self.options.enable_link_map_file and name.endswith(".map"): + continue path = os.path.join(self.output_dir, name) if os.path.isdir(path): for root, dirs, files in os.walk(path): for file in files: - outputs.update({ - file: os.path.join(root, file) - }) + yield BuilderOutput(os.path.join(root, file), file) else: - outputs.update({ - name: os.path.join(self.output_dir, name) - }) - - return outputs + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/infineon.py b/scripts/build/builders/infineon.py index 1cf7e0dd9b900d..8578fba45434a3 100644 --- a/scripts/build/builders/infineon.py +++ b/scripts/build/builders/infineon.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -102,19 +103,14 @@ def GnBuildArgs(self): return self.extra_gn_options def build_outputs(self): - items = { - '%s.out' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix()), - '%s.out.map' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix()), - } - - return items - - def flashbundle(self): - with open(os.path.join(self.output_dir, self.app.FlashBundleName()), 'r') as fp: - return { - line.strip(): os.path.join(self.output_dir, line.strip()) for line in fp.readlines() if line.strip() - } + extensions = ['out'] + if self.options.enable_link_map_file: + extensions.append('out.map') + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) + + def bundle_outputs(self): + with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: + for line in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput(os.path.join(self.output_dir, line), line) diff --git a/scripts/build/builders/mbed.py b/scripts/build/builders/mbed.py index fd2aa00ebd2f35..6dc47d0aa4aa27 100644 --- a/scripts/build/builders/mbed.py +++ b/scripts/build/builders/mbed.py @@ -16,7 +16,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class MbedApp(Enum): @@ -147,12 +147,9 @@ def _build(self): title='Building ' + self.identifier) def build_outputs(self): - return { - self.app.AppNamePrefix + '.elf': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.elf'), - self.app.AppNamePrefix + '.hex': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.hex'), - self.app.AppNamePrefix + '.map': - os.path.join(self.output_dir, - self.app.AppNamePrefix + '.elf.map'), - } + extensions = ['elf', 'hex'] + if self.options.enable_link_map_file: + extensions.append('elf.map') + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/mw320.py b/scripts/build/builders/mw320.py index 66b739321d8759..7fdf7578385eec 100755 --- a/scripts/build/builders/mw320.py +++ b/scripts/build/builders/mw320.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -49,9 +50,9 @@ def __init__(self, self.app = app def build_outputs(self): - items = {} - for extension in [".bin", ".out", ".out.map"]: - name = '%s%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) - - return items + extensions = ["bin", "out"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/nrf.py b/scripts/build/builders/nrf.py index 9bc4f9596efc26..d584490589c662 100644 --- a/scripts/build/builders/nrf.py +++ b/scripts/build/builders/nrf.py @@ -17,7 +17,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class NrfApp(Enum): @@ -225,23 +225,24 @@ def _build(self): self._Execute(['ctest', '--build-nocmake', '-V', '--output-on-failure', '--test-dir', self.output_dir], title='Run Tests ' + self.identifier) - def _generate_flashbundle(self): + def _bundle(self): logging.info(f'Generating flashbundle at {self.output_dir}') self._Execute(['ninja', '-C', self.output_dir, 'flashing_script'], title='Generating flashable files of ' + self.identifier) def build_outputs(self): - return { - '%s.elf' % self.app.AppNamePrefix(): os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), - '%s.map' % self.app.AppNamePrefix(): os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), - } - - def flashbundle(self): + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), + '%s.elf' % self.app.AppNamePrefix()) + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), + '%s.map' % self.app.AppNamePrefix()) + + def bundle_outputs(self): if self.app == NrfApp.UNIT_TESTS: - return dict() - - with open(os.path.join(self.output_dir, self.app.FlashBundleName()), 'r') as fp: - return { - line.strip(): os.path.join(self.output_dir, line.strip()) for line in fp.readlines() if line.strip() - } + return + with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: + for line in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput(os.path.join(self.output_dir, line), line) diff --git a/scripts/build/builders/nuttx.py b/scripts/build/builders/nuttx.py index ae198ca71f07ac..39bb2e78918667 100644 --- a/scripts/build/builders/nuttx.py +++ b/scripts/build/builders/nuttx.py @@ -16,6 +16,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import Builder @@ -86,13 +87,9 @@ def _build(self): def build_outputs(self): logging.info('Compiling outputs NuttX at %s', self.output_dir) - items = { - '%s.out' % self.app.AppNamePrefix(self.chip_name): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix(self.chip_name)), - '%s.out.map' % self.app.AppNamePrefix(self.chip_name): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix(self.chip_name)), - } - - return items + extensions = ["out"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix(self.chip_name)}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index 9f0dcfddd7bbde..4bd4f0ae451875 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -129,7 +130,10 @@ def generate(self): def build_outputs(self): name = 'chip-%s-%s' % (self.board.Name(), self.app.NameSuffix()) - return { - '%s.elf' % name: os.path.join(self.output_dir, name), - '%s.map' % name: os.path.join(self.output_dir, '%s.map' % name) - } + yield BuilderOutput( + os.path.join(self.output_dir, name), + f'{name}.elf') + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, f'{name}.map'), + f'{name}.map') diff --git a/scripts/build/builders/openiotsdk.py b/scripts/build/builders/openiotsdk.py index 89aad6a59e9a16..c0ea5facb92f70 100644 --- a/scripts/build/builders/openiotsdk.py +++ b/scripts/build/builders/openiotsdk.py @@ -16,7 +16,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class OpenIotSdkApp(Enum): @@ -90,10 +90,9 @@ def _build(self): title='Building ' + self.identifier) def build_outputs(self): - return { - self.app.AppNamePrefix + '.elf': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.elf'), - self.app.AppNamePrefix + '.map': - os.path.join(self.output_dir, - self.app.AppNamePrefix + '.map'), - } + extensions = ["elf"] + if self.options.enable_link_map_file: + extensions.append("map") + for ext in extensions: + name = f"{self.app.AppNamePrefix}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/qpg.py b/scripts/build/builders/qpg.py index ef3b6745058e02..330f4e3b74977d 100644 --- a/scripts/build/builders/qpg.py +++ b/scripts/build/builders/qpg.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -126,16 +127,16 @@ def GnBuildArgs(self): return args def build_outputs(self): - items = {} - for extension in ["out", "out.map", "out.hex"]: - name = '%s.%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) + extensions = ["out", "out.hex"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) # Figure out flash bundle files and build accordingly with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: - for line in f.readlines(): - name = line.strip() - items['flashbundle/%s' % - name] = os.path.join(self.output_dir, name) - - return items + for name in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput( + os.path.join(self.output_dir, name), + os.path.join('flashbundle', name)) diff --git a/scripts/build/builders/rw61x.py b/scripts/build/builders/rw61x.py index 546c6549e2aab9..b0c67dcbac68b1 100644 --- a/scripts/build/builders/rw61x.py +++ b/scripts/build/builders/rw61x.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -117,8 +118,10 @@ def generate(self): super(RW61XBuilder, self).generate() def build_outputs(self): - name = '%s' % self.app.NameSuffix() - return { - '%s.elf' % name: os.path.join(self.output_dir, name), - '%s.map' % name: os.path.join(self.output_dir, '%s.map' % name) - } + yield BuilderOutput( + os.path.join(self.output_dir, self.app.NameSuffix()), + f'{self.app.NameSuffix()}.elf') + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, f'{self.app.NameSuffix()}.map'), + f'{self.app.NameSuffix()}.map') diff --git a/scripts/build/builders/stm32.py b/scripts/build/builders/stm32.py index 1613ecbbe42f39..ae9d4f7b65c702 100644 --- a/scripts/build/builders/stm32.py +++ b/scripts/build/builders/stm32.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -78,16 +79,16 @@ def GnBuildArgs(self): return self.extra_gn_options def build_outputs(self): - items = {} - for extension in ["out", "out.map", "out.hex"]: - name = '%s.%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) + extensions = ["out", "out.hex"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) # Figure out flash bundle files and build accordingly with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: - for line in f.readlines(): - name = line.strip() - items['flashbundle/%s' % - name] = os.path.join(self.output_dir, name) - - return items + for name in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput( + os.path.join(self.output_dir, name), + os.path.join('flashbundle', name)) diff --git a/scripts/build/builders/telink.py b/scripts/build/builders/telink.py index 9b63635250dcf2..c53e0b6321cd76 100644 --- a/scripts/build/builders/telink.py +++ b/scripts/build/builders/telink.py @@ -17,7 +17,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class TelinkApp(Enum): @@ -229,15 +229,10 @@ def _build(self): self._Execute(['bash', '-c', cmd], title='Building ' + self.identifier) def build_outputs(self): - return { - '%s.elf' % - self.app.AppNamePrefix(): os.path.join( - self.output_dir, - 'zephyr', - 'zephyr.elf'), - '%s.map' % - self.app.AppNamePrefix(): os.path.join( - self.output_dir, - 'zephyr', - 'zephyr.map'), - } + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), + '%s.elf' % self.app.AppNamePrefix()) + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), + '%s.map' % self.app.AppNamePrefix()) diff --git a/scripts/build/builders/ti.py b/scripts/build/builders/ti.py index 5decd75cc058e0..f0691f541b3157 100644 --- a/scripts/build/builders/ti.py +++ b/scripts/build/builders/ti.py @@ -16,6 +16,7 @@ from enum import Enum, auto from typing import Optional +from .builder import BuilderOutput from .gn import GnBuilder @@ -104,6 +105,9 @@ def GnBuildArgs(self): args = [ 'ti_sysconfig_root="%s"' % os.environ['TI_SYSCONFIG_ROOT'], 'ti_simplelink_board="%s"' % self.board.BoardName(), + # FIXME: It seems that TI SDK expects link map file to be present. + # In order to make it optional, SDK fix is needed. + 'chip_generate_link_map_file=true', ] if self.openthread_ftd: @@ -115,22 +119,18 @@ def GnBuildArgs(self): return args def build_outputs(self): - items = {} - if (self.board == TIBoard.LP_EM_CC1354P10_6): - if (self.app == TIApp.LOCK - or self.app == TIApp.LIGHTING - or self.app == TIApp.PUMP - or self.app == TIApp.PUMP_CONTROLLER): - extensions = [".out", ".out.map", "-mcuboot.hex"] - + if self.board == TIBoard.LP_EM_CC1354P10_6: + if self.app in [TIApp.LOCK, + TIApp.LIGHTING, + TIApp.PUMP, + TIApp.PUMP_CONTROLLER]: + suffixes = [".out", "-mcuboot.hex"] else: - extensions = [".out", ".out.map"] - + suffixes = [".out"] else: - extensions = [".out", ".out.map"] - - for extension in extensions: - name = '%s%s' % (self.app.AppNamePrefix(self.board), extension) - items[name] = os.path.join(self.output_dir, name) - - return items + suffixes = [".out"] + if self.options.enable_link_map_file: + suffixes.append(".out.map") + for suffix in suffixes: + name = f"{self.app.AppNamePrefix(self.board)}{suffix}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/tizen.py b/scripts/build/builders/tizen.py index 6b5cdd90ec77f0..97124328c5dd1e 100644 --- a/scripts/build/builders/tizen.py +++ b/scripts/build/builders/tizen.py @@ -18,6 +18,7 @@ from enum import Enum from xml.etree import ElementTree as ET +from .builder import BuilderOutput from .gn import GnBuilder Board = namedtuple('Board', ['target_cpu']) @@ -147,23 +148,23 @@ def GnBuildArgs(self): 'tizen_sdk_sysroot="%s"' % os.environ['TIZEN_SDK_SYSROOT'], ] - def _generate_flashbundle(self): + def _bundle(self): if self.app.is_tpk: logging.info('Packaging %s', self.output_dir) cmd = ['ninja', '-C', self.output_dir, self.app.value.name + ':tpk'] self._Execute(cmd, title='Packaging ' + self.identifier) def build_outputs(self): - return { - output: os.path.join(self.output_dir, output) - for output in self.app.value.outputs - } - - def flashbundle(self): + for name in self.app.value.outputs: + if not self.options.enable_link_map_file and name.endswith(".map"): + continue + yield BuilderOutput( + os.path.join(self.output_dir, name), + name) + + def bundle_outputs(self): if not self.app.is_tpk: - return {} - return { - self.app.package: os.path.join(self.output_dir, - self.app.package_name, 'out', - self.app.package), - } + return + source = os.path.join(self.output_dir, self.app.package_name, + 'out', self.app.package) + yield BuilderOutput(source, self.app.package) diff --git a/src/test_driver/tizen/chip_tests/BUILD.gn b/src/test_driver/tizen/chip_tests/BUILD.gn index 01b0e5e70246be..829371df7cc620 100644 --- a/src/test_driver/tizen/chip_tests/BUILD.gn +++ b/src/test_driver/tizen/chip_tests/BUILD.gn @@ -30,7 +30,6 @@ tizen_qemu_mkisofs("chip-tests-runner") { # rebuild of the ISO image, so the test will be run with old # binaries. assets_non_tracked = [ rebase_path("${root_build_dir}/tests") ] - assets_non_tracked_exclude_globs = [ "*.map" ] } tizen_qemu_run("chip-tests") {