From 2b70fc5baed2a88a01a2a0670e1304751bacd399 Mon Sep 17 00:00:00 2001 From: Michael Schwarcz Date: Thu, 1 Nov 2018 13:10:34 +0200 Subject: [PATCH] Merge pull request #14 from theotherjimmy/artifact-delivery Artifact delivery # Conflicts: # tools/build_api.py # tools/config/__init__.py --- tools/build_api.py | 18 +++++++++++++++++- tools/config/__init__.py | 31 +++++++++++++++++++++++++++++-- tools/targets/__init__.py | 10 +++++++--- tools/utils.py | 17 +++++++++++++++++ 4 files changed, 70 insertions(+), 6 deletions(-) diff --git a/tools/build_api.py b/tools/build_api.py index 28c6007e135..65baa307eae 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -35,7 +35,7 @@ from .arm_pack_manager import Cache from .utils import (mkdir, run_cmd, run_cmd_ext, NotSupportedException, ToolException, InvalidReleaseTargetException, - intelhex_offset, integer, generate_update_filename) + intelhex_offset, integer, generate_update_filename, copy_when_different) from .paths import (MBED_CMSIS_PATH, MBED_TARGETS_PATH, MBED_LIBRARIES, MBED_HEADER, MBED_DRIVERS, MBED_PLATFORM, MBED_HAL, MBED_CONFIG_FILE, MBED_LIBRARIES_DRIVERS, @@ -560,6 +560,22 @@ def build_project(src_paths, build_path, target, toolchain_name, res, _ = toolchain.link_program(resources, build_path, name) res = (res, None) + into_dir, extra_artifacts = toolchain.config.deliver_into() + if into_dir: + mkdir(into_dir) + copy_when_different(res[0], into_dir) + if not extra_artifacts: + if ( + CORE_ARCH[toolchain.target.core] == 8 and + not toolchain.target.core.endswith("NS") + ): + cmse_lib = join(dirname(res[0]), "cmse_lib.o") + copy_when_different(cmse_lib, into_dir) + else: + for tc, art in extra_artifacts: + if toolchain_name == tc: + copy_when_different(join(build_path, art), into_dir) + memap_instance = getattr(toolchain, 'memap_instance', None) memap_table = '' if memap_instance: diff --git a/tools/config/__init__.py b/tools/config/__init__.py index b83067c9644..582cba2da0f 100644 --- a/tools/config/__init__.py +++ b/tools/config/__init__.py @@ -41,7 +41,15 @@ unicode except NameError: unicode = str -PATH_OVERRIDES = set(["target.bootloader_img"]) +PATH_OVERRIDES = set([ + "target.bootloader_img", + "target.delivery_dir", +]) +DELIVERY_OVERRIDES = set([ + "target.delivery_dir", + "target.deliver_to_target", + "target.deliver_artifacts", +]) ROM_OVERRIDES = set([ # managed BL "target.bootloader_img", "target.restrict_size", @@ -59,7 +67,7 @@ "target.mbed_ram_start", "target.mbed_ram_size", ]) -BOOTLOADER_OVERRIDES = ROM_OVERRIDES | RAM_OVERRIDES +BOOTLOADER_OVERRIDES = ROM_OVERRIDES | RAM_OVERRIDES | DELIVERY_OVERRIDES ALLOWED_FEATURES = [ @@ -493,10 +501,17 @@ def __init__(self, tgt, top_level_dirs=None, app_config=None): self.app_config_data.get("custom_targets", {}), tgt) self.target = deepcopy(self.target) self.target_labels = self.target.labels + po_without_target = set(o.split(".")[1] for o in PATH_OVERRIDES) for override in BOOTLOADER_OVERRIDES: _, attr = override.split(".") if not hasattr(self.target, attr): setattr(self.target, attr, None) + elif attr in po_without_target: + new_path = join( + dirname(self.target._from_file), + getattr(self.target, attr) + ) + setattr( self.target, attr, new_path) self.cumulative_overrides = {key: ConfigCumulativeOverride(key) for key in CUMULATIVE_ATTRIBUTES} @@ -573,6 +588,18 @@ def has_ram_regions(self): return True return False + def deliver_into(self): + if self.target.delivery_dir: + label_dir = "TARGET_{}".format( + self.target.deliver_to_target or self.target.name + ) + return ( + join(self.target.delivery_dir, label_dir), + self.target.deliver_artifacts + ) + else: + return None, None + @property def sectors(self): """Return a list of tuples of sector start,size""" diff --git a/tools/targets/__init__.py b/tools/targets/__init__.py index 42677cadf0c..7b3c5229eae 100644 --- a/tools/targets/__init__.py +++ b/tools/targets/__init__.py @@ -162,8 +162,12 @@ class Target(namedtuple("Target", "name json_data resolution_order resolution_or @cached def get_json_target_data(): """Load the description of JSON target data""" - targets = json_file_to_dict(Target.__targets_json_location or - Target.__targets_json_location_default) + from_file = (Target.__targets_json_location or + Target.__targets_json_location_default) + + targets = json_file_to_dict(from_file) + for tgt in targets.values(): + tgt["_from_file"] = from_file for extra_target in Target.__extra_target_json_files: for k, v in json_file_to_dict(extra_target).items(): @@ -172,6 +176,7 @@ def get_json_target_data(): 'target.' % k) else: targets[k] = v + targets[k]["_from_file"] = extra_target return targets @@ -610,4 +615,3 @@ def set_targets_json_location(location=None): # instead. This ensures compatibility with code that does # "from tools.targets import TARGET_NAMES" update_target_data() - diff --git a/tools/utils.py b/tools/utils.py index 368b968a465..fb8869c29cc 100644 --- a/tools/utils.py +++ b/tools/utils.py @@ -215,6 +215,23 @@ def copy_file(src, dst): copyfile(src, dst) +def copy_when_different(src, dst): + """ Only copy the file when it's different from its destination. + + Positional arguments: + src - the source of the copy operation + dst - the destination of the copy operation + """ + if isdir(dst): + _, base = split(src) + dst = join(dst, base) + if exists(dst): + with open(src, 'rb') as srcfd, open(dst, 'rb') as dstfd: + if srcfd.read() == dstfd.read(): + return + copyfile(src, dst) + + def delete_dir_files(directory): """ A function that does rm -rf