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