relocation.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #! /usr/bin/env python
  2. # encoding: utf-8
  3. """
  4. Waf 1.6
  5. Try to detect if the project directory was relocated, and if it was,
  6. change the node representing the project directory. Just call:
  7. waf configure build
  8. Note that if the project directory name changes, the signatures for the tasks using
  9. files in that directory will change, causing a partial build.
  10. """
  11. import os
  12. from waflib import Build, ConfigSet, Task, Utils, Errors
  13. from waflib.TaskGen import feature, after_method
  14. EXTRA_LOCK = '.old_srcdir'
  15. old1 = Build.BuildContext.store
  16. def store(self):
  17. old1(self)
  18. db = os.path.join(self.variant_dir, EXTRA_LOCK)
  19. env = ConfigSet.ConfigSet()
  20. env.SRCDIR = self.srcnode.abspath()
  21. env.store(db)
  22. Build.BuildContext.store = store
  23. old2 = Build.BuildContext.init_dirs
  24. def init_dirs(self):
  25. if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)):
  26. raise Errors.WafError('The project was not configured: run "waf configure" first!')
  27. srcdir = None
  28. db = os.path.join(self.variant_dir, EXTRA_LOCK)
  29. env = ConfigSet.ConfigSet()
  30. try:
  31. env.load(db)
  32. srcdir = env.SRCDIR
  33. except:
  34. pass
  35. if srcdir:
  36. d = self.root.find_node(srcdir)
  37. if d and srcdir != self.top_dir and getattr(d, 'children', ''):
  38. srcnode = self.root.make_node(self.top_dir)
  39. print("relocating the source directory %r -> %r" % (srcdir, self.top_dir))
  40. srcnode.children = {}
  41. for (k, v) in d.children.items():
  42. srcnode.children[k] = v
  43. v.parent = srcnode
  44. d.children = {}
  45. old2(self)
  46. Build.BuildContext.init_dirs = init_dirs
  47. def uid(self):
  48. try:
  49. return self.uid_
  50. except AttributeError:
  51. # this is not a real hot zone, but we want to avoid surprises here
  52. m = Utils.md5()
  53. up = m.update
  54. up(self.__class__.__name__.encode())
  55. for x in self.inputs + self.outputs:
  56. up(x.path_from(x.ctx.srcnode).encode())
  57. self.uid_ = m.digest()
  58. return self.uid_
  59. Task.Task.uid = uid
  60. @feature('c', 'cxx', 'd', 'go', 'asm', 'fc', 'includes')
  61. @after_method('propagate_uselib_vars', 'process_source')
  62. def apply_incpaths(self):
  63. lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES'])
  64. self.includes_nodes = lst
  65. bld = self.bld
  66. self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.bldnode) or x.abspath() for x in lst]