Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hooks.py Source File

hooks.py

00001 """ Configurable hooks in the build system. Can be used by various platforms
00002 to customize the build process.
00003 """
00004 
00005 ################################################################################
00006 # Hooks for the various parts of the build process
00007 
00008 # Internal mapping of hooks per tool
00009 _HOOKS = {}
00010 
00011 # Internal mapping of running hooks
00012 _RUNNING_HOOKS = {}
00013 
00014 # Available hook types
00015 _HOOK_TYPES = ["binary", "compile", "link", "assemble"]
00016 
00017 # Available hook steps
00018 _HOOK_STEPS = ["pre", "replace", "post"]
00019 
00020 # Hook the given function. Use this function as a decorator
00021 def hook_tool (function):
00022     """Decorate a function as a tool that may be hooked"""
00023     tool = function.__name__
00024     tool_flag = "_" + tool + "_done"
00025     def wrapper(t_self, *args, **kwargs):
00026         """The hooked function itself"""
00027         # if a hook for this tool is already running, it's most likely
00028         # coming from a derived class, so don't hook the super class version
00029         if _RUNNING_HOOKS.get(tool, False):
00030             return function(t_self, *args, **kwargs)
00031         _RUNNING_HOOKS[tool] = True
00032         # If this tool isn't hooked, return original function
00033         if not _HOOKS.has_key(tool):
00034             res = function(t_self, *args, **kwargs)
00035             _RUNNING_HOOKS[tool] = False
00036             return res
00037         tooldesc = _HOOKS[tool]
00038         setattr(t_self, tool_flag, False)
00039         # If there is a replace hook, execute the replacement instead
00040         if tooldesc.has_key("replace"):
00041             res = tooldesc["replace"](t_self, *args, **kwargs)
00042         # If the replacement has set the "done" flag, exit now
00043         # Otherwise continue as usual
00044         if getattr(t_self, tool_flag, False):
00045             _RUNNING_HOOKS[tool] = False
00046             return res
00047         # Execute pre-function before main function if specified
00048         if tooldesc.has_key("pre"):
00049             tooldesc["pre"](t_self, *args, **kwargs)
00050         # Execute the main function now
00051         res = function(t_self, *args, **kwargs)
00052         # Execute post-function after main function if specified
00053         if tooldesc.has_key("post"):
00054             post_res = tooldesc["post"](t_self, *args, **kwargs)
00055             _RUNNING_HOOKS[tool] = False
00056             return post_res or res
00057         else:
00058             _RUNNING_HOOKS[tool] = False
00059             return res
00060     return wrapper
00061 
00062 class Hook (object):
00063     """A compiler class that may be hooked"""
00064     def __init__(self, target, toolchain):
00065         _HOOKS.clear()
00066         self._cmdline_hooks  = {}
00067         self.toolchain  = toolchain
00068         target.init_hooks(self, toolchain)
00069 
00070     # Hook various functions directly
00071     @staticmethod
00072     def _hook_add(hook_type, hook_step, function):
00073         """Add a hook to a compile function
00074 
00075         Positional arguments:
00076         hook_type - one of the _HOOK_TYPES
00077         hook_step - one of the _HOOK_STEPS
00078         function - the function to add to the list of hooks
00079         """
00080         if hook_type not in _HOOK_TYPES or hook_step not in _HOOK_STEPS:
00081             return False
00082         if hook_type not in _HOOKS:
00083             _HOOKS[hook_type] = {}
00084         _HOOKS[hook_type][hook_step] = function
00085         return True
00086 
00087     def hook_add_compiler (self, hook_step, function):
00088         """Add a hook to the compiler
00089 
00090         Positional Arguments:
00091         hook_step - one of the _HOOK_STEPS
00092         function - the function to add to the list of hooks
00093         """
00094         return self._hook_add ("compile", hook_step, function)
00095 
00096     def hook_add_linker (self, hook_step, function):
00097         """Add a hook to the linker
00098 
00099         Positional Arguments:
00100         hook_step - one of the _HOOK_STEPS
00101         function - the function to add to the list of hooks
00102         """
00103         return self._hook_add ("link", hook_step, function)
00104 
00105     def hook_add_assembler (self, hook_step, function):
00106         """Add a hook to the assemble
00107 
00108         Positional Arguments:
00109         hook_step - one of the _HOOK_STEPS
00110         function - the function to add to the list of hooks
00111         """
00112         return self._hook_add ("assemble", hook_step, function)
00113 
00114     def hook_add_binary (self, hook_step, function):
00115         """Add a hook to the elf to binary tool
00116 
00117         Positional Arguments:
00118         hook_step - one of the _HOOK_STEPS
00119         function - the function to add to the list of hooks
00120         """
00121         return self._hook_add ("binary", hook_step, function)
00122 
00123     # Hook command lines
00124     def _hook_cmdline(self, hook_type, function):
00125         """Add a hook to a command line function
00126 
00127         Positional arguments:
00128         hook_type - one of the _HOOK_TYPES
00129         function - the function to add to the list of hooks
00130         """
00131         if hook_type not in _HOOK_TYPES:
00132             return False
00133         self._cmdline_hooks [hook_type] = function
00134         return True
00135 
00136     def hook_cmdline_compiler (self, function):
00137         """Add a hook to the compiler command line
00138 
00139         Positional arguments:
00140         function - the function to call
00141         """
00142         return self._hook_cmdline ("compile", function)
00143 
00144     def hook_cmdline_linker (self, function):
00145         """Add a hook to the linker command line
00146 
00147         Positional arguments:
00148         function - the function to call
00149         """
00150         return self._hook_cmdline ("link", function)
00151 
00152     def hook_cmdline_assembler (self, function):
00153         """Add a hook to the assembler command line
00154 
00155         Positional arguments:
00156         function - the function to call
00157         """
00158         return self._hook_cmdline ("assemble", function)
00159 
00160     def hook_cmdline_binary (self, function):
00161         """Add a hook to the elf to bin tool command line
00162 
00163         Positional arguments:
00164         function - the function to call
00165         """
00166         return self._hook_cmdline ("binary", function)
00167 
00168     # Return the command line after applying the hook
00169     def _get_cmdline(self, hook_type, cmdline):
00170         """Get the command line after running all hooks
00171 
00172         Positional arguments:
00173         hook_type - one of the _HOOK_TYPES
00174         cmdline - the initial command line
00175         """
00176         if self._cmdline_hooks .has_key(hook_type):
00177             cmdline = self._cmdline_hooks [hook_type](
00178                 self.toolchain .__class__.__name__, cmdline)
00179         return cmdline
00180 
00181     def get_cmdline_compiler (self, cmdline):
00182         """Get the compiler command line after running all hooks
00183 
00184         Positional arguments:
00185         cmdline - the initial command line
00186         """
00187         return self._get_cmdline ("compile", cmdline)
00188 
00189     def get_cmdline_linker (self, cmdline):
00190         """Get the linker command line after running all hooks
00191 
00192         Positional arguments:
00193         cmdline - the initial command line
00194         """
00195         return self._get_cmdline ("link", cmdline)
00196 
00197     def get_cmdline_assembler (self, cmdline):
00198         """Get the assmebler command line after running all hooks
00199 
00200         Positional arguments:
00201         cmdline - the initial command line
00202         """
00203         return self._get_cmdline ("assemble", cmdline)
00204 
00205     def get_cmdline_binary (self, cmdline):
00206         """Get the binary command line after running all hooks
00207 
00208         Positional arguments:
00209         cmdline - the initial command line
00210         """
00211         return self._get_cmdline ("binary", cmdline)
00212 
00213 ################################################################################
00214