BBR 1 Ebene

Committer:
borlanic
Date:
Mon May 14 11:29:06 2018 +0000
Revision:
0:fbdae7e6d805
BBR

Who changed what in which revision?

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