summaryrefslogtreecommitdiffstats
path: root/extras/stale.py
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-03-17 17:31:05 +0100
committerDavid Robillard <d@drobilla.net>2019-03-17 17:31:05 +0100
commit406f89271452fdb573c7e28113b1ed08ff2b4eda (patch)
treed2dcbaf61f3749f73dc7a5e10d3fc6cd5e6e129a /extras/stale.py
parent7983a5aae615290d04fd43cbc2752f8cf4a46d10 (diff)
downloadsuil-406f89271452fdb573c7e28113b1ed08ff2b4eda.tar.gz
suil-406f89271452fdb573c7e28113b1ed08ff2b4eda.tar.bz2
suil-406f89271452fdb573c7e28113b1ed08ff2b4eda.zip
Squashed 'waflib/' changes from 915dcb1..e7a29b6
e7a29b6 Upgrade to waf 2.0.15 8280f9d Add command for running executables from the build directory 8073c1a Make make_simple_dox() safe in case of exception 70d03b8 Avoid use of global counter hacks for configuration display b7d689a Rewrite test framework 94deadf Automatically add options and move add_flags() to options context f4259ee Reduce system include path noise 927b608 Automatically display configuration header c44b8f3 Set line justification from a constant in the wscript a48e26f Automatically detect if wscript has a test hook ef66724 Save runtime variables in the environment 63bcbcd Clean up TestContext b1d9505 Add ExecutionContext for setting runtime environment 387c1df Add show_diff() and test_file_equals() utilities 29d4d29 Fix in-tree library paths 9fde01f Add custom configuration context 6d3612f Add lib_path_name constant git-subtree-dir: waflib git-subtree-split: e7a29b6b9b2f842314244c23c14d8f8f560904e1
Diffstat (limited to 'extras/stale.py')
-rw-r--r--extras/stale.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/extras/stale.py b/extras/stale.py
new file mode 100644
index 0000000..cac3f46
--- /dev/null
+++ b/extras/stale.py
@@ -0,0 +1,98 @@
+#! /usr/bin/env python
+# encoding: UTF-8
+# Thomas Nagy, 2006-2015 (ita)
+
+"""
+Add a pre-build hook to remove build files (declared in the system)
+that do not have a corresponding target
+
+This can be used for example to remove the targets
+that have changed name without performing
+a full 'waf clean'
+
+Of course, it will only work if there are no dynamically generated
+nodes/tasks, in which case the method will have to be modified
+to exclude some folders for example.
+
+Make sure to set bld.post_mode = waflib.Build.POST_AT_ONCE
+"""
+
+from waflib import Logs, Build
+from waflib.Runner import Parallel
+
+DYNAMIC_EXT = [] # add your non-cleanable files/extensions here
+MOC_H_EXTS = '.cpp .cxx .hpp .hxx .h'.split()
+
+def can_delete(node):
+ """Imperfect moc cleanup which does not look for a Q_OBJECT macro in the files"""
+ if not node.name.endswith('.moc'):
+ return True
+ base = node.name[:-4]
+ p1 = node.parent.get_src()
+ p2 = node.parent.get_bld()
+ for k in MOC_H_EXTS:
+ h_name = base + k
+ n = p1.search_node(h_name)
+ if n:
+ return False
+ n = p2.search_node(h_name)
+ if n:
+ return False
+
+ # foo.cpp.moc, foo.h.moc, etc.
+ if base.endswith(k):
+ return False
+
+ return True
+
+# recursion over the nodes to find the stale files
+def stale_rec(node, nodes):
+ if node.abspath() in node.ctx.env[Build.CFG_FILES]:
+ return
+
+ if getattr(node, 'children', []):
+ for x in node.children.values():
+ if x.name != "c4che":
+ stale_rec(x, nodes)
+ else:
+ for ext in DYNAMIC_EXT:
+ if node.name.endswith(ext):
+ break
+ else:
+ if not node in nodes:
+ if can_delete(node):
+ Logs.warn('Removing stale file -> %r', node)
+ node.delete()
+
+old = Parallel.refill_task_list
+def refill_task_list(self):
+ iit = old(self)
+ bld = self.bld
+
+ # execute this operation only once
+ if getattr(self, 'stale_done', False):
+ return iit
+ self.stale_done = True
+
+ # this does not work in partial builds
+ if bld.targets != '*':
+ return iit
+
+ # this does not work in dynamic builds
+ if getattr(bld, 'post_mode') == Build.POST_AT_ONCE:
+ return iit
+
+ # obtain the nodes to use during the build
+ nodes = []
+ for tasks in bld.groups:
+ for x in tasks:
+ try:
+ nodes.extend(x.outputs)
+ except AttributeError:
+ pass
+
+ stale_rec(bld.bldnode, nodes)
+ return iit
+
+Parallel.refill_task_list = refill_task_list
+