diff --git a/tools/hooks.py b/tools/hooks.py deleted file mode 100644 index f3b5265702..0000000000 --- a/tools/hooks.py +++ /dev/null @@ -1,214 +0,0 @@ -""" Configurable hooks in the build system. Can be used by various platforms -to customize the build process. -""" - -################################################################################ -# Hooks for the various parts of the build process - -# Internal mapping of hooks per tool -_HOOKS = {} - -# Internal mapping of running hooks -_RUNNING_HOOKS = {} - -# Available hook types -_HOOK_TYPES = ["binary", "compile", "link", "assemble"] - -# Available hook steps -_HOOK_STEPS = ["pre", "replace", "post"] - -# Hook the given function. Use this function as a decorator -def hook_tool(function): - """Decorate a function as a tool that may be hooked""" - tool = function.__name__ - tool_flag = "_" + tool + "_done" - def wrapper(t_self, *args, **kwargs): - """The hooked function itself""" - # if a hook for this tool is already running, it's most likely - # coming from a derived class, so don't hook the super class version - if _RUNNING_HOOKS.get(tool, False): - return function(t_self, *args, **kwargs) - _RUNNING_HOOKS[tool] = True - # If this tool isn't hooked, return original function - if tool not in _HOOKS: - res = function(t_self, *args, **kwargs) - _RUNNING_HOOKS[tool] = False - return res - tooldesc = _HOOKS[tool] - setattr(t_self, tool_flag, False) - # If there is a replace hook, execute the replacement instead - if "replace" in tooldesc: - res = tooldesc["replace"](t_self, *args, **kwargs) - # If the replacement has set the "done" flag, exit now - # Otherwise continue as usual - if getattr(t_self, tool_flag, False): - _RUNNING_HOOKS[tool] = False - return res - # Execute pre-function before main function if specified - if "pre" in tooldesc: - tooldesc["pre"](t_self, *args, **kwargs) - # Execute the main function now - res = function(t_self, *args, **kwargs) - # Execute post-function after main function if specified - if "post" in tooldesc: - post_res = tooldesc["post"](t_self, *args, **kwargs) - _RUNNING_HOOKS[tool] = False - return post_res or res - else: - _RUNNING_HOOKS[tool] = False - return res - return wrapper - -class Hook(object): - """A compiler class that may be hooked""" - def __init__(self, target, toolchain): - _HOOKS.clear() - self._cmdline_hooks = {} - self.toolchain = toolchain - target.init_hooks(self, toolchain) - - # Hook various functions directly - @staticmethod - def _hook_add(hook_type, hook_step, function): - """Add a hook to a compile function - - Positional arguments: - hook_type - one of the _HOOK_TYPES - hook_step - one of the _HOOK_STEPS - function - the function to add to the list of hooks - """ - if hook_type not in _HOOK_TYPES or hook_step not in _HOOK_STEPS: - return False - if hook_type not in _HOOKS: - _HOOKS[hook_type] = {} - _HOOKS[hook_type][hook_step] = function - return True - - def hook_add_compiler(self, hook_step, function): - """Add a hook to the compiler - - Positional Arguments: - hook_step - one of the _HOOK_STEPS - function - the function to add to the list of hooks - """ - return self._hook_add("compile", hook_step, function) - - def hook_add_linker(self, hook_step, function): - """Add a hook to the linker - - Positional Arguments: - hook_step - one of the _HOOK_STEPS - function - the function to add to the list of hooks - """ - return self._hook_add("link", hook_step, function) - - def hook_add_assembler(self, hook_step, function): - """Add a hook to the assemble - - Positional Arguments: - hook_step - one of the _HOOK_STEPS - function - the function to add to the list of hooks - """ - return self._hook_add("assemble", hook_step, function) - - def hook_add_binary(self, hook_step, function): - """Add a hook to the elf to binary tool - - Positional Arguments: - hook_step - one of the _HOOK_STEPS - function - the function to add to the list of hooks - """ - return self._hook_add("binary", hook_step, function) - - # Hook command lines - def _hook_cmdline(self, hook_type, function): - """Add a hook to a command line function - - Positional arguments: - hook_type - one of the _HOOK_TYPES - function - the function to add to the list of hooks - """ - if hook_type not in _HOOK_TYPES: - return False - self._cmdline_hooks[hook_type] = function - return True - - def hook_cmdline_compiler(self, function): - """Add a hook to the compiler command line - - Positional arguments: - function - the function to call - """ - return self._hook_cmdline("compile", function) - - def hook_cmdline_linker(self, function): - """Add a hook to the linker command line - - Positional arguments: - function - the function to call - """ - return self._hook_cmdline("link", function) - - def hook_cmdline_assembler(self, function): - """Add a hook to the assembler command line - - Positional arguments: - function - the function to call - """ - return self._hook_cmdline("assemble", function) - - def hook_cmdline_binary(self, function): - """Add a hook to the elf to bin tool command line - - Positional arguments: - function - the function to call - """ - return self._hook_cmdline("binary", function) - - # Return the command line after applying the hook - def _get_cmdline(self, hook_type, cmdline): - """Get the command line after running all hooks - - Positional arguments: - hook_type - one of the _HOOK_TYPES - cmdline - the initial command line - """ - if hook_type in self._cmdline_hooks: - cmdline = self._cmdline_hooks[hook_type]( - self.toolchain.__class__.__name__, cmdline) - return cmdline - - def get_cmdline_compiler(self, cmdline): - """Get the compiler command line after running all hooks - - Positional arguments: - cmdline - the initial command line - """ - return self._get_cmdline("compile", cmdline) - - def get_cmdline_linker(self, cmdline): - """Get the linker command line after running all hooks - - Positional arguments: - cmdline - the initial command line - """ - return self._get_cmdline("link", cmdline) - - def get_cmdline_assembler(self, cmdline): - """Get the assmebler command line after running all hooks - - Positional arguments: - cmdline - the initial command line - """ - return self._get_cmdline("assemble", cmdline) - - def get_cmdline_binary(self, cmdline): - """Get the binary command line after running all hooks - - Positional arguments: - cmdline - the initial command line - """ - return self._get_cmdline("binary", cmdline) - -################################################################################ - diff --git a/tools/targets/__init__.py b/tools/targets/__init__.py index 6c7fbc642c..451116338d 100644 --- a/tools/targets/__init__.py +++ b/tools/targets/__init__.py @@ -355,7 +355,7 @@ class Target(namedtuple("Target", "name json_data resolution_order resolution_or def is_PSA_non_secure_target(self): return 'NSPE_Target' in self.labels - def init_hooks(self, hook, toolchain): + def get_post_build_hook(self, toolchain): """Initialize the post-build hooks for a toolchain. For now, this function only allows "post binary" hooks (hooks that are executed after the binary image is extracted from the executable file) @@ -404,8 +404,7 @@ class Target(namedtuple("Target", "name json_data resolution_order resolution_or if toolchain_restrictions and \ not toolchain_labels.intersection(toolchain_restrictions): return - # Finally, hook the requested function - hook.hook_add_binary("post", getattr(cls, function_name)) + return getattr(cls, function_name) ################################################################################ # Target specific code goes in this section diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 4c6ee457bf..14ec346b9b 100755 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -36,7 +36,6 @@ from hashlib import md5 from ..utils import (run_cmd, mkdir, rel_path, ToolException, NotSupportedException, split_path, compile_worker) from ..settings import MBED_ORG_USER, PRINT_COMPILER_OUTPUT_AS_LINK -from .. import hooks from ..notifier.term import TerminalNotifier from ..resources import FileType from ..memap import MemapParser @@ -96,7 +95,7 @@ class mbedToolchain: self.name = self.__class__.__name__ # compile/assemble/link/binary hooks - self.hook = hooks.Hook(target, self) + self._post_build_hook = target.get_post_build_hook(self.name) # Toolchain flags self.flags = deepcopy(build_profile or self.profile_template) @@ -653,6 +652,9 @@ class mbedToolchain: self.progress("elf2bin", name) self.binary(r, elf, bin) + if self._post_build_hook: + self.progress("post-build", name) + self._post_build_hook(self, r, elf, bin) # Initialize memap and process map file. This doesn't generate output. self.mem_stats(mapfile) @@ -1002,9 +1004,6 @@ class mbedToolchain: Side effects: None - - Note: - This method should be decorated with @hook_tool. """ raise NotImplemented @@ -1024,9 +1023,6 @@ class mbedToolchain: Side effects: None - - Note: - This method should be decorated with @hook_tool. """ raise NotImplemented @@ -1046,9 +1042,6 @@ class mbedToolchain: Side effects: None - - Note: - This method should be decorated with @hook_tool. """ raise NotImplemented @@ -1068,9 +1061,6 @@ class mbedToolchain: Side effect: Runs the linker to produce the executable. - - Note: - This method should be decorated with @hook_tool. """ raise NotImplemented @@ -1087,9 +1077,6 @@ class mbedToolchain: Side effect: Runs the archiving tool to produce the library file. - - Note: - This method should be decorated with @hook_tool. """ raise NotImplemented @@ -1107,9 +1094,6 @@ class mbedToolchain: Side effect: Runs the elf2bin tool to produce the simplified binary file. - - Note: - This method should be decorated with @hook_tool. """ raise NotImplemented diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index 82cfcdce66..9e9028837a 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -27,7 +27,6 @@ from distutils.version import LooseVersion from tools.targets import CORE_ARCH from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS -from tools.hooks import hook_tool from tools.utils import mkdir, NotSupportedException, run_cmd class ARM(mbedToolchain): @@ -192,7 +191,6 @@ class ARM(mbedToolchain): return opts - @hook_tool def assemble(self, source, object, includes): # Preprocess first, then assemble dir = join(dirname(object), '.temp') @@ -208,14 +206,9 @@ class ARM(mbedToolchain): # Build main assemble command cmd = self.asm + ["-o", object, tempfile] - # Call cmdline hook - cmd_pre = self.hook.get_cmdline_assembler(cmd_pre) - cmd = self.hook.get_cmdline_assembler(cmd) - # Return command array, don't execute return [cmd_pre, cmd] - @hook_tool def compile(self, cc, source, object, includes): # Build compile command cmd = cc + self.get_compile_options(self.get_symbols(), includes) @@ -224,9 +217,6 @@ class ARM(mbedToolchain): cmd.extend(["-o", object, source]) - # Call cmdline hook - cmd = self.hook.get_cmdline_compiler(cmd) - return [cmd] def compile_c(self, source, object, includes): @@ -269,7 +259,6 @@ class ARM(mbedToolchain): return new_scatter - @hook_tool def link(self, output, objects, libraries, lib_dirs, scatter_file): base, _ = splitext(output) map_file = base + ".map" @@ -283,7 +272,6 @@ class ARM(mbedToolchain): args.extend(["--scatter", new_scatter]) cmd_pre = self.ld + args - cmd = self.hook.get_cmdline_linker(cmd_pre) if self.RESPONSE_FILES: cmd_linker = cmd[0] @@ -293,7 +281,6 @@ class ARM(mbedToolchain): self.notify.cc_verbose("Link: %s" % ' '.join(cmd)) self.default_cmd(cmd) - @hook_tool def archive(self, objects, lib_path): if self.RESPONSE_FILES: param = ['--via', self.get_arch_file(objects)] @@ -301,13 +288,11 @@ class ARM(mbedToolchain): param = objects self.default_cmd([self.ar, '-r', lib_path] + param) - @hook_tool def binary(self, resources, elf, bin): _, fmt = splitext(bin) # On .hex format, combine multiple .hex files (for multiple load regions) into one bin_arg = {".bin": "--bin", ".hex": "--i32combined"}[fmt] cmd = [self.elf2bin, bin_arg, '-o', bin, elf] - cmd = self.hook.get_cmdline_binary(cmd) # remove target binary file/path if exists(bin): @@ -518,18 +503,15 @@ class ARMC6(ARM_STD): "--cpreproc_opts=%s" % ",".join(self.flags['common'] + opts)] return opts - @hook_tool def assemble(self, source, object, includes): cmd_pre = copy(self.asm) cmd_pre.extend(self.get_compile_options( self.get_symbols(True), includes, for_asm=True)) cmd_pre.extend(["-o", object, source]) - return [self.hook.get_cmdline_assembler(cmd_pre)] + return [cmd_pre] - @hook_tool def compile(self, cc, source, object, includes): cmd = copy(cc) cmd.extend(self.get_compile_options(self.get_symbols(), includes)) cmd.extend(["-o", object, source]) - cmd = self.hook.get_cmdline_compiler(cmd) return [cmd] diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py index 56348bd589..6ecf63dd2e 100644 --- a/tools/toolchains/gcc.py +++ b/tools/toolchains/gcc.py @@ -22,7 +22,6 @@ from distutils.version import LooseVersion from tools.targets import CORE_ARCH from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS -from tools.hooks import hook_tool from tools.utils import run_cmd, NotSupportedException class GCC(mbedToolchain): @@ -195,18 +194,13 @@ class GCC(mbedToolchain): opts = opts + self.get_config_option(config_header) return opts - @hook_tool def assemble(self, source, object, includes): # Build assemble command cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes) + ["-o", object, source] - # Call cmdline hook - cmd = self.hook.get_cmdline_assembler(cmd) - # Return command array, don't execute return [cmd] - @hook_tool def compile(self, cc, source, object, includes): # Build compile command cmd = cc + self.get_compile_options(self.get_symbols(), includes) @@ -215,8 +209,6 @@ class GCC(mbedToolchain): cmd.extend(["-o", object, source]) - # Call cmdline hook - cmd = self.hook.get_cmdline_compiler(cmd) if self.use_distcc: cmd = ["distcc"] + cmd @@ -228,7 +220,6 @@ class GCC(mbedToolchain): def compile_cpp(self, source, object, includes): return self.compile(self.cppc, source, object, includes) - @hook_tool def link(self, output, objects, libraries, lib_dirs, mem_map): libs = [] for l in libraries: @@ -256,9 +247,6 @@ class GCC(mbedToolchain): cmd.extend(['-L', L]) cmd.extend(libs) - # Call cmdline hook - cmd = self.hook.get_cmdline_linker(cmd) - if self.RESPONSE_FILES: # Split link command to linker executable + response file cmd_linker = cmd[0] @@ -269,7 +257,6 @@ class GCC(mbedToolchain): self.notify.cc_verbose("Link: %s" % ' '.join(cmd)) self.default_cmd(cmd) - @hook_tool def archive(self, objects, lib_path): if self.RESPONSE_FILES: param = ["@%s" % self.get_arch_file(objects)] @@ -279,16 +266,12 @@ class GCC(mbedToolchain): # Exec command self.default_cmd([self.ar, 'rcs', lib_path] + param) - @hook_tool def binary(self, resources, elf, bin): # Build binary command _, fmt = splitext(bin) bin_arg = {'.bin': 'binary', '.hex': 'ihex'}[fmt] cmd = [self.elf2bin, "-O", bin_arg, elf, bin] - # Call cmdline hook - cmd = self.hook.get_cmdline_binary(cmd) - # Exec command self.notify.cc_verbose("FromELF: %s" % ' '.join(cmd)) self.default_cmd(cmd) diff --git a/tools/toolchains/iar.py b/tools/toolchains/iar.py index 7751795aad..cb099bd2f0 100644 --- a/tools/toolchains/iar.py +++ b/tools/toolchains/iar.py @@ -21,7 +21,6 @@ from distutils.version import LooseVersion from tools.targets import CORE_ARCH from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS -from tools.hooks import hook_tool from tools.utils import run_cmd, NotSupportedException class IAR(mbedToolchain): @@ -185,7 +184,6 @@ class IAR(mbedToolchain): return opts - @hook_tool def assemble(self, source, object, includes): # Build assemble command cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes, True) + ["-o", object, source] @@ -196,7 +194,6 @@ class IAR(mbedToolchain): # Return command array, don't execute return [cmd] - @hook_tool def compile(self, cc, source, object, includes): # Build compile command cmd = cc + self.get_compile_options(self.get_symbols(), includes) @@ -218,7 +215,6 @@ class IAR(mbedToolchain): def compile_cpp(self, source, object, includes): return self.compile(self.cppc, source, object, includes) - @hook_tool def link(self, output, objects, libraries, lib_dirs, mem_map): # Build linker command map_file = splitext(output)[0] + ".map" @@ -240,7 +236,6 @@ class IAR(mbedToolchain): self.notify.cc_verbose("Link: %s" % ' '.join(cmd)) self.default_cmd(cmd) - @hook_tool def archive(self, objects, lib_path): if self.RESPONSE_FILES: param = ['-f', self.get_arch_file(objects)] @@ -252,16 +247,12 @@ class IAR(mbedToolchain): self.default_cmd([self.ar, lib_path] + param) - @hook_tool def binary(self, resources, elf, bin): _, fmt = splitext(bin) bin_arg = {".bin": "--bin", ".hex": "--ihex"}[fmt] # Build binary command cmd = [self.elf2bin, bin_arg, elf, bin] - # Call cmdline hook - cmd = self.hook.get_cmdline_binary(cmd) - # Exec command self.notify.cc_verbose("FromELF: %s" % ' '.join(cmd)) self.default_cmd(cmd)