strip_hack.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #! /usr/bin/env python
  2. """
  3. This is a hack; In general two tasks should not provide
  4. the same output nodes (bad abstraction), and this cannot
  5. scale to more than one operation
  6. In this case, the strip task has the same inputs as outputs
  7. so the constraints added by Task.set_file_constraints
  8. to prevent race conditions:
  9. - By setting the input node to be the link task output node
  10. the strip tasks will run after their link tasks
  11. - By setting the output node to be the link task output node,
  12. any other task that also uses this output node will wait
  13. for the strip task to finish too
  14. - By overriding the runnable_status method, the strip task
  15. will avoid the deadlock and force itself to run only when
  16. the link task has run
  17. """
  18. def configure(conf):
  19. conf.find_program('strip')
  20. from waflib import Task, TaskGen
  21. class strip(Task.Task):
  22. run_str = '${STRIP} ${SRC}'
  23. color = 'BLUE'
  24. no_errcheck_out = True
  25. def keyword(self):
  26. return 'Stripping'
  27. def runnable_status(self):
  28. if self in self.run_after:
  29. self.run_after.remove(self)
  30. ret = super(strip, self).runnable_status()
  31. if ret == Task.ASK_LATER:
  32. return ret
  33. if self.generator.link_task.hasrun == Task.SUCCESS:
  34. # ensure that stripping always runs
  35. # when a binary is written
  36. return Task.RUN_ME
  37. return Task.SKIP_ME
  38. @TaskGen.feature('cshlib', 'cxxshlib', 'cprogram', 'cxxprogram', 'fcprogram', 'fcshlib')
  39. @TaskGen.after('apply_link')
  40. def add_strip_task(self):
  41. if getattr(self, 'link_task', None):
  42. exe_node = self.link_task.outputs[0]
  43. # special case: same inputs and outputs for a task
  44. self.create_task('strip', exe_node, exe_node)