waf

FORK: waf with some random patches
git clone https://git.neptards.moe/neptards/waf.git
Log | Files | Refs | README

stale.py (2297B)


      1 #! /usr/bin/env python
      2 # encoding: UTF-8
      3 # Thomas Nagy, 2006-2015 (ita)
      4 
      5 """
      6 Add a pre-build hook to remove build files (declared in the system)
      7 that do not have a corresponding target
      8 
      9 This can be used for example to remove the targets
     10 that have changed name without performing
     11 a full 'waf clean'
     12 
     13 Of course, it will only work if there are no dynamically generated
     14 nodes/tasks, in which case the method will have to be modified
     15 to exclude some folders for example.
     16 
     17 Make sure to set bld.post_mode = waflib.Build.POST_AT_ONCE
     18 """
     19 
     20 from waflib import Logs, Build
     21 from waflib.Runner import Parallel
     22 
     23 DYNAMIC_EXT = [] # add your non-cleanable files/extensions here
     24 MOC_H_EXTS = '.cpp .cxx .hpp .hxx .h'.split()
     25 
     26 def can_delete(node):
     27 	"""Imperfect moc cleanup which does not look for a Q_OBJECT macro in the files"""
     28 	if not node.name.endswith('.moc'):
     29 		return True
     30 	base = node.name[:-4]
     31 	p1 = node.parent.get_src()
     32 	p2 = node.parent.get_bld()
     33 	for k in MOC_H_EXTS:
     34 		h_name = base + k
     35 		n = p1.search_node(h_name)
     36 		if n:
     37 			return False
     38 		n = p2.search_node(h_name)
     39 		if n:
     40 			return False
     41 
     42 		# foo.cpp.moc, foo.h.moc, etc.
     43 		if base.endswith(k):
     44 			return False
     45 
     46 	return True
     47 
     48 # recursion over the nodes to find the stale files
     49 def stale_rec(node, nodes):
     50 	if node.abspath() in node.ctx.env[Build.CFG_FILES]:
     51 		return
     52 
     53 	if getattr(node, 'children', []):
     54 		for x in node.children.values():
     55 			if x.name != "c4che":
     56 				stale_rec(x, nodes)
     57 	else:
     58 		for ext in DYNAMIC_EXT:
     59 			if node.name.endswith(ext):
     60 				break
     61 		else:
     62 			if not node in nodes:
     63 				if can_delete(node):
     64 					Logs.warn('Removing stale file -> %r', node)
     65 					node.delete()
     66 
     67 old = Parallel.refill_task_list
     68 def refill_task_list(self):
     69 	iit = old(self)
     70 	bld = self.bld
     71 
     72 	# execute this operation only once
     73 	if getattr(self, 'stale_done', False):
     74 		return iit
     75 	self.stale_done = True
     76 
     77 	# this does not work in partial builds
     78 	if bld.targets != '*':
     79 		return iit
     80 
     81 	# this does not work in dynamic builds
     82 	if getattr(bld, 'post_mode') == Build.POST_AT_ONCE:
     83 		return iit
     84 
     85 	# obtain the nodes to use during the build
     86 	nodes = []
     87 	for tasks in bld.groups:
     88 		for x in tasks:
     89 			try:
     90 				nodes.extend(x.outputs)
     91 			except AttributeError:
     92 				pass
     93 
     94 	stale_rec(bld.bldnode, nodes)
     95 	return iit
     96 
     97 Parallel.refill_task_list = refill_task_list
     98