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-sdk-tools by
hooks.py
- Committer:
- screamer
- Date:
- 2016-08-29
- Revision:
- 29:1210849dba19
- Parent:
- 0:66f3b5499f7f
File content as of revision 29:1210849dba19:
""" 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 not _HOOKS.has_key(tool):
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 tooldesc.has_key("replace"):
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 tooldesc.has_key("pre"):
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 tooldesc.has_key("post"):
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.__class__.__name__)
# 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 self._cmdline_hooks.has_key(hook_type):
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)
################################################################################
