Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
tools/hooks.py@0:f269e3021894, 2016-10-23 (annotated)
- Committer:
- elessair
- Date:
- Sun Oct 23 15:10:02 2016 +0000
- Revision:
- 0:f269e3021894
Initial commit
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| elessair | 0:f269e3021894 | 1 | """ Configurable hooks in the build system. Can be used by various platforms |
| elessair | 0:f269e3021894 | 2 | to customize the build process. |
| elessair | 0:f269e3021894 | 3 | """ |
| elessair | 0:f269e3021894 | 4 | |
| elessair | 0:f269e3021894 | 5 | ################################################################################ |
| elessair | 0:f269e3021894 | 6 | # Hooks for the various parts of the build process |
| elessair | 0:f269e3021894 | 7 | |
| elessair | 0:f269e3021894 | 8 | # Internal mapping of hooks per tool |
| elessair | 0:f269e3021894 | 9 | _HOOKS = {} |
| elessair | 0:f269e3021894 | 10 | |
| elessair | 0:f269e3021894 | 11 | # Internal mapping of running hooks |
| elessair | 0:f269e3021894 | 12 | _RUNNING_HOOKS = {} |
| elessair | 0:f269e3021894 | 13 | |
| elessair | 0:f269e3021894 | 14 | # Available hook types |
| elessair | 0:f269e3021894 | 15 | _HOOK_TYPES = ["binary", "compile", "link", "assemble"] |
| elessair | 0:f269e3021894 | 16 | |
| elessair | 0:f269e3021894 | 17 | # Available hook steps |
| elessair | 0:f269e3021894 | 18 | _HOOK_STEPS = ["pre", "replace", "post"] |
| elessair | 0:f269e3021894 | 19 | |
| elessair | 0:f269e3021894 | 20 | # Hook the given function. Use this function as a decorator |
| elessair | 0:f269e3021894 | 21 | def hook_tool(function): |
| elessair | 0:f269e3021894 | 22 | """Decorate a function as a tool that may be hooked""" |
| elessair | 0:f269e3021894 | 23 | tool = function.__name__ |
| elessair | 0:f269e3021894 | 24 | tool_flag = "_" + tool + "_done" |
| elessair | 0:f269e3021894 | 25 | def wrapper(t_self, *args, **kwargs): |
| elessair | 0:f269e3021894 | 26 | """The hooked function itself""" |
| elessair | 0:f269e3021894 | 27 | # if a hook for this tool is already running, it's most likely |
| elessair | 0:f269e3021894 | 28 | # coming from a derived class, so don't hook the super class version |
| elessair | 0:f269e3021894 | 29 | if _RUNNING_HOOKS.get(tool, False): |
| elessair | 0:f269e3021894 | 30 | return function(t_self, *args, **kwargs) |
| elessair | 0:f269e3021894 | 31 | _RUNNING_HOOKS[tool] = True |
| elessair | 0:f269e3021894 | 32 | # If this tool isn't hooked, return original function |
| elessair | 0:f269e3021894 | 33 | if not _HOOKS.has_key(tool): |
| elessair | 0:f269e3021894 | 34 | res = function(t_self, *args, **kwargs) |
| elessair | 0:f269e3021894 | 35 | _RUNNING_HOOKS[tool] = False |
| elessair | 0:f269e3021894 | 36 | return res |
| elessair | 0:f269e3021894 | 37 | tooldesc = _HOOKS[tool] |
| elessair | 0:f269e3021894 | 38 | setattr(t_self, tool_flag, False) |
| elessair | 0:f269e3021894 | 39 | # If there is a replace hook, execute the replacement instead |
| elessair | 0:f269e3021894 | 40 | if tooldesc.has_key("replace"): |
| elessair | 0:f269e3021894 | 41 | res = tooldesc["replace"](t_self, *args, **kwargs) |
| elessair | 0:f269e3021894 | 42 | # If the replacement has set the "done" flag, exit now |
| elessair | 0:f269e3021894 | 43 | # Otherwise continue as usual |
| elessair | 0:f269e3021894 | 44 | if getattr(t_self, tool_flag, False): |
| elessair | 0:f269e3021894 | 45 | _RUNNING_HOOKS[tool] = False |
| elessair | 0:f269e3021894 | 46 | return res |
| elessair | 0:f269e3021894 | 47 | # Execute pre-function before main function if specified |
| elessair | 0:f269e3021894 | 48 | if tooldesc.has_key("pre"): |
| elessair | 0:f269e3021894 | 49 | tooldesc["pre"](t_self, *args, **kwargs) |
| elessair | 0:f269e3021894 | 50 | # Execute the main function now |
| elessair | 0:f269e3021894 | 51 | res = function(t_self, *args, **kwargs) |
| elessair | 0:f269e3021894 | 52 | # Execute post-function after main function if specified |
| elessair | 0:f269e3021894 | 53 | if tooldesc.has_key("post"): |
| elessair | 0:f269e3021894 | 54 | post_res = tooldesc["post"](t_self, *args, **kwargs) |
| elessair | 0:f269e3021894 | 55 | _RUNNING_HOOKS[tool] = False |
| elessair | 0:f269e3021894 | 56 | return post_res or res |
| elessair | 0:f269e3021894 | 57 | else: |
| elessair | 0:f269e3021894 | 58 | _RUNNING_HOOKS[tool] = False |
| elessair | 0:f269e3021894 | 59 | return res |
| elessair | 0:f269e3021894 | 60 | return wrapper |
| elessair | 0:f269e3021894 | 61 | |
| elessair | 0:f269e3021894 | 62 | class Hook(object): |
| elessair | 0:f269e3021894 | 63 | """A compiler class that may be hooked""" |
| elessair | 0:f269e3021894 | 64 | def __init__(self, target, toolchain): |
| elessair | 0:f269e3021894 | 65 | _HOOKS.clear() |
| elessair | 0:f269e3021894 | 66 | self._cmdline_hooks = {} |
| elessair | 0:f269e3021894 | 67 | self.toolchain = toolchain |
| elessair | 0:f269e3021894 | 68 | target.init_hooks(self, toolchain.__class__.__name__) |
| elessair | 0:f269e3021894 | 69 | |
| elessair | 0:f269e3021894 | 70 | # Hook various functions directly |
| elessair | 0:f269e3021894 | 71 | @staticmethod |
| elessair | 0:f269e3021894 | 72 | def _hook_add(hook_type, hook_step, function): |
| elessair | 0:f269e3021894 | 73 | """Add a hook to a compile function |
| elessair | 0:f269e3021894 | 74 | |
| elessair | 0:f269e3021894 | 75 | Positional arguments: |
| elessair | 0:f269e3021894 | 76 | hook_type - one of the _HOOK_TYPES |
| elessair | 0:f269e3021894 | 77 | hook_step - one of the _HOOK_STEPS |
| elessair | 0:f269e3021894 | 78 | function - the function to add to the list of hooks |
| elessair | 0:f269e3021894 | 79 | """ |
| elessair | 0:f269e3021894 | 80 | if hook_type not in _HOOK_TYPES or hook_step not in _HOOK_STEPS: |
| elessair | 0:f269e3021894 | 81 | return False |
| elessair | 0:f269e3021894 | 82 | if hook_type not in _HOOKS: |
| elessair | 0:f269e3021894 | 83 | _HOOKS[hook_type] = {} |
| elessair | 0:f269e3021894 | 84 | _HOOKS[hook_type][hook_step] = function |
| elessair | 0:f269e3021894 | 85 | return True |
| elessair | 0:f269e3021894 | 86 | |
| elessair | 0:f269e3021894 | 87 | def hook_add_compiler(self, hook_step, function): |
| elessair | 0:f269e3021894 | 88 | """Add a hook to the compiler |
| elessair | 0:f269e3021894 | 89 | |
| elessair | 0:f269e3021894 | 90 | Positional Arguments: |
| elessair | 0:f269e3021894 | 91 | hook_step - one of the _HOOK_STEPS |
| elessair | 0:f269e3021894 | 92 | function - the function to add to the list of hooks |
| elessair | 0:f269e3021894 | 93 | """ |
| elessair | 0:f269e3021894 | 94 | return self._hook_add("compile", hook_step, function) |
| elessair | 0:f269e3021894 | 95 | |
| elessair | 0:f269e3021894 | 96 | def hook_add_linker(self, hook_step, function): |
| elessair | 0:f269e3021894 | 97 | """Add a hook to the linker |
| elessair | 0:f269e3021894 | 98 | |
| elessair | 0:f269e3021894 | 99 | Positional Arguments: |
| elessair | 0:f269e3021894 | 100 | hook_step - one of the _HOOK_STEPS |
| elessair | 0:f269e3021894 | 101 | function - the function to add to the list of hooks |
| elessair | 0:f269e3021894 | 102 | """ |
| elessair | 0:f269e3021894 | 103 | return self._hook_add("link", hook_step, function) |
| elessair | 0:f269e3021894 | 104 | |
| elessair | 0:f269e3021894 | 105 | def hook_add_assembler(self, hook_step, function): |
| elessair | 0:f269e3021894 | 106 | """Add a hook to the assemble |
| elessair | 0:f269e3021894 | 107 | |
| elessair | 0:f269e3021894 | 108 | Positional Arguments: |
| elessair | 0:f269e3021894 | 109 | hook_step - one of the _HOOK_STEPS |
| elessair | 0:f269e3021894 | 110 | function - the function to add to the list of hooks |
| elessair | 0:f269e3021894 | 111 | """ |
| elessair | 0:f269e3021894 | 112 | return self._hook_add("assemble", hook_step, function) |
| elessair | 0:f269e3021894 | 113 | |
| elessair | 0:f269e3021894 | 114 | def hook_add_binary(self, hook_step, function): |
| elessair | 0:f269e3021894 | 115 | """Add a hook to the elf to binary tool |
| elessair | 0:f269e3021894 | 116 | |
| elessair | 0:f269e3021894 | 117 | Positional Arguments: |
| elessair | 0:f269e3021894 | 118 | hook_step - one of the _HOOK_STEPS |
| elessair | 0:f269e3021894 | 119 | function - the function to add to the list of hooks |
| elessair | 0:f269e3021894 | 120 | """ |
| elessair | 0:f269e3021894 | 121 | return self._hook_add("binary", hook_step, function) |
| elessair | 0:f269e3021894 | 122 | |
| elessair | 0:f269e3021894 | 123 | # Hook command lines |
| elessair | 0:f269e3021894 | 124 | def _hook_cmdline(self, hook_type, function): |
| elessair | 0:f269e3021894 | 125 | """Add a hook to a command line function |
| elessair | 0:f269e3021894 | 126 | |
| elessair | 0:f269e3021894 | 127 | Positional arguments: |
| elessair | 0:f269e3021894 | 128 | hook_type - one of the _HOOK_TYPES |
| elessair | 0:f269e3021894 | 129 | function - the function to add to the list of hooks |
| elessair | 0:f269e3021894 | 130 | """ |
| elessair | 0:f269e3021894 | 131 | if hook_type not in _HOOK_TYPES: |
| elessair | 0:f269e3021894 | 132 | return False |
| elessair | 0:f269e3021894 | 133 | self._cmdline_hooks[hook_type] = function |
| elessair | 0:f269e3021894 | 134 | return True |
| elessair | 0:f269e3021894 | 135 | |
| elessair | 0:f269e3021894 | 136 | def hook_cmdline_compiler(self, function): |
| elessair | 0:f269e3021894 | 137 | """Add a hook to the compiler command line |
| elessair | 0:f269e3021894 | 138 | |
| elessair | 0:f269e3021894 | 139 | Positional arguments: |
| elessair | 0:f269e3021894 | 140 | function - the function to call |
| elessair | 0:f269e3021894 | 141 | """ |
| elessair | 0:f269e3021894 | 142 | return self._hook_cmdline("compile", function) |
| elessair | 0:f269e3021894 | 143 | |
| elessair | 0:f269e3021894 | 144 | def hook_cmdline_linker(self, function): |
| elessair | 0:f269e3021894 | 145 | """Add a hook to the linker command line |
| elessair | 0:f269e3021894 | 146 | |
| elessair | 0:f269e3021894 | 147 | Positional arguments: |
| elessair | 0:f269e3021894 | 148 | function - the function to call |
| elessair | 0:f269e3021894 | 149 | """ |
| elessair | 0:f269e3021894 | 150 | return self._hook_cmdline("link", function) |
| elessair | 0:f269e3021894 | 151 | |
| elessair | 0:f269e3021894 | 152 | def hook_cmdline_assembler(self, function): |
| elessair | 0:f269e3021894 | 153 | """Add a hook to the assembler command line |
| elessair | 0:f269e3021894 | 154 | |
| elessair | 0:f269e3021894 | 155 | Positional arguments: |
| elessair | 0:f269e3021894 | 156 | function - the function to call |
| elessair | 0:f269e3021894 | 157 | """ |
| elessair | 0:f269e3021894 | 158 | return self._hook_cmdline("assemble", function) |
| elessair | 0:f269e3021894 | 159 | |
| elessair | 0:f269e3021894 | 160 | def hook_cmdline_binary(self, function): |
| elessair | 0:f269e3021894 | 161 | """Add a hook to the elf to bin tool command line |
| elessair | 0:f269e3021894 | 162 | |
| elessair | 0:f269e3021894 | 163 | Positional arguments: |
| elessair | 0:f269e3021894 | 164 | function - the function to call |
| elessair | 0:f269e3021894 | 165 | """ |
| elessair | 0:f269e3021894 | 166 | return self._hook_cmdline("binary", function) |
| elessair | 0:f269e3021894 | 167 | |
| elessair | 0:f269e3021894 | 168 | # Return the command line after applying the hook |
| elessair | 0:f269e3021894 | 169 | def _get_cmdline(self, hook_type, cmdline): |
| elessair | 0:f269e3021894 | 170 | """Get the command line after running all hooks |
| elessair | 0:f269e3021894 | 171 | |
| elessair | 0:f269e3021894 | 172 | Positional arguments: |
| elessair | 0:f269e3021894 | 173 | hook_type - one of the _HOOK_TYPES |
| elessair | 0:f269e3021894 | 174 | cmdline - the initial command line |
| elessair | 0:f269e3021894 | 175 | """ |
| elessair | 0:f269e3021894 | 176 | if self._cmdline_hooks.has_key(hook_type): |
| elessair | 0:f269e3021894 | 177 | cmdline = self._cmdline_hooks[hook_type]( |
| elessair | 0:f269e3021894 | 178 | self.toolchain.__class__.__name__, cmdline) |
| elessair | 0:f269e3021894 | 179 | return cmdline |
| elessair | 0:f269e3021894 | 180 | |
| elessair | 0:f269e3021894 | 181 | def get_cmdline_compiler(self, cmdline): |
| elessair | 0:f269e3021894 | 182 | """Get the compiler command line after running all hooks |
| elessair | 0:f269e3021894 | 183 | |
| elessair | 0:f269e3021894 | 184 | Positional arguments: |
| elessair | 0:f269e3021894 | 185 | cmdline - the initial command line |
| elessair | 0:f269e3021894 | 186 | """ |
| elessair | 0:f269e3021894 | 187 | return self._get_cmdline("compile", cmdline) |
| elessair | 0:f269e3021894 | 188 | |
| elessair | 0:f269e3021894 | 189 | def get_cmdline_linker(self, cmdline): |
| elessair | 0:f269e3021894 | 190 | """Get the linker command line after running all hooks |
| elessair | 0:f269e3021894 | 191 | |
| elessair | 0:f269e3021894 | 192 | Positional arguments: |
| elessair | 0:f269e3021894 | 193 | cmdline - the initial command line |
| elessair | 0:f269e3021894 | 194 | """ |
| elessair | 0:f269e3021894 | 195 | return self._get_cmdline("link", cmdline) |
| elessair | 0:f269e3021894 | 196 | |
| elessair | 0:f269e3021894 | 197 | def get_cmdline_assembler(self, cmdline): |
| elessair | 0:f269e3021894 | 198 | """Get the assmebler command line after running all hooks |
| elessair | 0:f269e3021894 | 199 | |
| elessair | 0:f269e3021894 | 200 | Positional arguments: |
| elessair | 0:f269e3021894 | 201 | cmdline - the initial command line |
| elessair | 0:f269e3021894 | 202 | """ |
| elessair | 0:f269e3021894 | 203 | return self._get_cmdline("assemble", cmdline) |
| elessair | 0:f269e3021894 | 204 | |
| elessair | 0:f269e3021894 | 205 | def get_cmdline_binary(self, cmdline): |
| elessair | 0:f269e3021894 | 206 | """Get the binary command line after running all hooks |
| elessair | 0:f269e3021894 | 207 | |
| elessair | 0:f269e3021894 | 208 | Positional arguments: |
| elessair | 0:f269e3021894 | 209 | cmdline - the initial command line |
| elessair | 0:f269e3021894 | 210 | """ |
| elessair | 0:f269e3021894 | 211 | return self._get_cmdline("binary", cmdline) |
| elessair | 0:f269e3021894 | 212 | |
| elessair | 0:f269e3021894 | 213 | ################################################################################ |
| elessair | 0:f269e3021894 | 214 |
