Clone of official tools
hooks.py@0:66f3b5499f7f, 2016-05-19 (annotated)
- Committer:
- screamer
- Date:
- Thu May 19 19:44:41 2016 +0100
- Revision:
- 0:66f3b5499f7f
- Child:
- 29:1210849dba19
Initial revision
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
screamer | 0:66f3b5499f7f | 1 | # Configurable hooks in the build system. Can be used by various platforms |
screamer | 0:66f3b5499f7f | 2 | # to customize the build process. |
screamer | 0:66f3b5499f7f | 3 | |
screamer | 0:66f3b5499f7f | 4 | ################################################################################ |
screamer | 0:66f3b5499f7f | 5 | # Hooks for the various parts of the build process |
screamer | 0:66f3b5499f7f | 6 | |
screamer | 0:66f3b5499f7f | 7 | # Internal mapping of hooks per tool |
screamer | 0:66f3b5499f7f | 8 | _hooks = {} |
screamer | 0:66f3b5499f7f | 9 | |
screamer | 0:66f3b5499f7f | 10 | # Internal mapping of running hooks |
screamer | 0:66f3b5499f7f | 11 | _running_hooks = {} |
screamer | 0:66f3b5499f7f | 12 | |
screamer | 0:66f3b5499f7f | 13 | # Available hook types |
screamer | 0:66f3b5499f7f | 14 | _hook_types = ["binary", "compile", "link", "assemble"] |
screamer | 0:66f3b5499f7f | 15 | |
screamer | 0:66f3b5499f7f | 16 | # Available hook steps |
screamer | 0:66f3b5499f7f | 17 | _hook_steps = ["pre", "replace", "post"] |
screamer | 0:66f3b5499f7f | 18 | |
screamer | 0:66f3b5499f7f | 19 | # Hook the given function. Use this function as a decorator |
screamer | 0:66f3b5499f7f | 20 | def hook_tool(function): |
screamer | 0:66f3b5499f7f | 21 | tool = function.__name__ |
screamer | 0:66f3b5499f7f | 22 | tool_flag = "_" + tool + "_done" |
screamer | 0:66f3b5499f7f | 23 | def wrapper(t_self, *args, **kwargs): |
screamer | 0:66f3b5499f7f | 24 | # if a hook for this tool is already running, it's most likely |
screamer | 0:66f3b5499f7f | 25 | # coming from a derived class, so don't hook the super class version |
screamer | 0:66f3b5499f7f | 26 | if _running_hooks.get(tool, False): |
screamer | 0:66f3b5499f7f | 27 | return function(t_self, *args, **kwargs) |
screamer | 0:66f3b5499f7f | 28 | _running_hooks[tool] = True |
screamer | 0:66f3b5499f7f | 29 | # If this tool isn't hooked, return original function |
screamer | 0:66f3b5499f7f | 30 | if not _hooks.has_key(tool): |
screamer | 0:66f3b5499f7f | 31 | res = function(t_self, *args, **kwargs) |
screamer | 0:66f3b5499f7f | 32 | _running_hooks[tool] = False |
screamer | 0:66f3b5499f7f | 33 | return res |
screamer | 0:66f3b5499f7f | 34 | tooldesc = _hooks[tool] |
screamer | 0:66f3b5499f7f | 35 | setattr(t_self, tool_flag, False) |
screamer | 0:66f3b5499f7f | 36 | # If there is a replace hook, execute the replacement instead |
screamer | 0:66f3b5499f7f | 37 | if tooldesc.has_key("replace"): |
screamer | 0:66f3b5499f7f | 38 | res = tooldesc["replace"](t_self, *args, **kwargs) |
screamer | 0:66f3b5499f7f | 39 | # If the replacement has set the "done" flag, exit now |
screamer | 0:66f3b5499f7f | 40 | # Otherwise continue as usual |
screamer | 0:66f3b5499f7f | 41 | if getattr(t_self, tool_flag, False): |
screamer | 0:66f3b5499f7f | 42 | _running_hooks[tool] = False |
screamer | 0:66f3b5499f7f | 43 | return res |
screamer | 0:66f3b5499f7f | 44 | # Execute pre-function before main function if specified |
screamer | 0:66f3b5499f7f | 45 | if tooldesc.has_key("pre"): |
screamer | 0:66f3b5499f7f | 46 | tooldesc["pre"](t_self, *args, **kwargs) |
screamer | 0:66f3b5499f7f | 47 | # Execute the main function now |
screamer | 0:66f3b5499f7f | 48 | res = function(t_self, *args, **kwargs) |
screamer | 0:66f3b5499f7f | 49 | # Execute post-function after main function if specified |
screamer | 0:66f3b5499f7f | 50 | if tooldesc.has_key("post"): |
screamer | 0:66f3b5499f7f | 51 | post_res = tooldesc["post"](t_self, *args, **kwargs) |
screamer | 0:66f3b5499f7f | 52 | _running_hooks[tool] = False |
screamer | 0:66f3b5499f7f | 53 | return post_res or res |
screamer | 0:66f3b5499f7f | 54 | else: |
screamer | 0:66f3b5499f7f | 55 | _running_hooks[tool] = False |
screamer | 0:66f3b5499f7f | 56 | return res |
screamer | 0:66f3b5499f7f | 57 | return wrapper |
screamer | 0:66f3b5499f7f | 58 | |
screamer | 0:66f3b5499f7f | 59 | class Hook: |
screamer | 0:66f3b5499f7f | 60 | def __init__(self, target, toolchain): |
screamer | 0:66f3b5499f7f | 61 | _hooks.clear() |
screamer | 0:66f3b5499f7f | 62 | self._cmdline_hooks = {} |
screamer | 0:66f3b5499f7f | 63 | self.toolchain = toolchain |
screamer | 0:66f3b5499f7f | 64 | target.init_hooks(self, toolchain.__class__.__name__) |
screamer | 0:66f3b5499f7f | 65 | |
screamer | 0:66f3b5499f7f | 66 | # Hook various functions directly |
screamer | 0:66f3b5499f7f | 67 | def _hook_add(self, hook_type, hook_step, function): |
screamer | 0:66f3b5499f7f | 68 | if not hook_type in _hook_types or not hook_step in _hook_steps: |
screamer | 0:66f3b5499f7f | 69 | return False |
screamer | 0:66f3b5499f7f | 70 | if not hook_type in _hooks: |
screamer | 0:66f3b5499f7f | 71 | _hooks[hook_type] = {} |
screamer | 0:66f3b5499f7f | 72 | _hooks[hook_type][hook_step] = function |
screamer | 0:66f3b5499f7f | 73 | return True |
screamer | 0:66f3b5499f7f | 74 | |
screamer | 0:66f3b5499f7f | 75 | def hook_add_compiler(self, hook_step, function): |
screamer | 0:66f3b5499f7f | 76 | return self._hook_add("compile", hook_step, function) |
screamer | 0:66f3b5499f7f | 77 | |
screamer | 0:66f3b5499f7f | 78 | def hook_add_linker(self, hook_step, function): |
screamer | 0:66f3b5499f7f | 79 | return self._hook_add("link", hook_step, function) |
screamer | 0:66f3b5499f7f | 80 | |
screamer | 0:66f3b5499f7f | 81 | def hook_add_assembler(self, hook_step, function): |
screamer | 0:66f3b5499f7f | 82 | return self._hook_add("assemble", hook_step, function) |
screamer | 0:66f3b5499f7f | 83 | |
screamer | 0:66f3b5499f7f | 84 | def hook_add_binary(self, hook_step, function): |
screamer | 0:66f3b5499f7f | 85 | return self._hook_add("binary", hook_step, function) |
screamer | 0:66f3b5499f7f | 86 | |
screamer | 0:66f3b5499f7f | 87 | # Hook command lines |
screamer | 0:66f3b5499f7f | 88 | def _hook_cmdline(self, hook_type, function): |
screamer | 0:66f3b5499f7f | 89 | if not hook_type in _hook_types: |
screamer | 0:66f3b5499f7f | 90 | return False |
screamer | 0:66f3b5499f7f | 91 | self._cmdline_hooks[hook_type] = function |
screamer | 0:66f3b5499f7f | 92 | return True |
screamer | 0:66f3b5499f7f | 93 | |
screamer | 0:66f3b5499f7f | 94 | def hook_cmdline_compiler(self, function): |
screamer | 0:66f3b5499f7f | 95 | return self._hook_cmdline("compile", function) |
screamer | 0:66f3b5499f7f | 96 | |
screamer | 0:66f3b5499f7f | 97 | def hook_cmdline_linker(self, function): |
screamer | 0:66f3b5499f7f | 98 | return self._hook_cmdline("link", function) |
screamer | 0:66f3b5499f7f | 99 | |
screamer | 0:66f3b5499f7f | 100 | def hook_cmdline_assembler(self, function): |
screamer | 0:66f3b5499f7f | 101 | return self._hook_cmdline("assemble", function) |
screamer | 0:66f3b5499f7f | 102 | |
screamer | 0:66f3b5499f7f | 103 | def hook_cmdline_binary(self, function): |
screamer | 0:66f3b5499f7f | 104 | return self._hook_cmdline("binary", function) |
screamer | 0:66f3b5499f7f | 105 | |
screamer | 0:66f3b5499f7f | 106 | # Return the command line after applying the hook |
screamer | 0:66f3b5499f7f | 107 | def _get_cmdline(self, hook_type, cmdline): |
screamer | 0:66f3b5499f7f | 108 | if self._cmdline_hooks.has_key(hook_type): |
screamer | 0:66f3b5499f7f | 109 | cmdline = self._cmdline_hooks[hook_type](self.toolchain.__class__.__name__, cmdline) |
screamer | 0:66f3b5499f7f | 110 | return cmdline |
screamer | 0:66f3b5499f7f | 111 | |
screamer | 0:66f3b5499f7f | 112 | def get_cmdline_compiler(self, cmdline): |
screamer | 0:66f3b5499f7f | 113 | return self._get_cmdline("compile", cmdline) |
screamer | 0:66f3b5499f7f | 114 | |
screamer | 0:66f3b5499f7f | 115 | def get_cmdline_linker(self, cmdline): |
screamer | 0:66f3b5499f7f | 116 | return self._get_cmdline("link", cmdline) |
screamer | 0:66f3b5499f7f | 117 | |
screamer | 0:66f3b5499f7f | 118 | def get_cmdline_assembler(self, cmdline): |
screamer | 0:66f3b5499f7f | 119 | return self._get_cmdline("assemble", cmdline) |
screamer | 0:66f3b5499f7f | 120 | |
screamer | 0:66f3b5499f7f | 121 | def get_cmdline_binary(self, cmdline): |
screamer | 0:66f3b5499f7f | 122 | return self._get_cmdline("binary", cmdline) |
screamer | 0:66f3b5499f7f | 123 | |
screamer | 0:66f3b5499f7f | 124 | ################################################################################ |
screamer | 0:66f3b5499f7f | 125 |