You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

hooks.py 4.5KB

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