thirdparty:waf: Update gccdeps from upstream
[sfrench/samba-autobuild/.git] / third_party / waf / wafadmin / 3rdparty / gccdeps.py
1 #!/usr/bin/env python
2 # encoding: utf-8
3 # Thomas Nagy, 2008-2010 (ita)
4
5 """
6 Execute the tasks with gcc -MD, read the dependencies from the .d file
7 and prepare the dependency calculation for the next run
8 """
9
10 import os, re, threading
11 import Task, Logs, Utils, preproc
12 from TaskGen import before, after, feature
13
14 lock = threading.Lock()
15
16 preprocessor_flag = '-MD'
17
18 @feature('cc', 'c')
19 @before('apply_core')
20 def add_mmd_cc(self):
21         if self.env.get_flat('CCFLAGS').find(preprocessor_flag) < 0:
22                 self.env.append_value('CCFLAGS', preprocessor_flag)
23
24 @feature('cxx')
25 @before('apply_core')
26 def add_mmd_cxx(self):
27         if self.env.get_flat('CXXFLAGS').find(preprocessor_flag) < 0:
28                 self.env.append_value('CXXFLAGS', preprocessor_flag)
29
30 def scan(self):
31         "the scanner does not do anything initially"
32         nodes = self.generator.bld.node_deps.get(self.unique_id(), [])
33         names = []
34         return (nodes, names)
35
36 re_o = re.compile("\.o$")
37 re_src = re.compile("^(\.\.)[\\/](.*)$")
38
39 def post_run(self):
40         # The following code is executed by threads, it is not safe, so a lock is needed...
41
42         if getattr(self, 'cached', None):
43                 return Task.Task.post_run(self)
44
45         name = self.outputs[0].abspath(self.env)
46         name = re_o.sub('.d', name)
47         txt = Utils.readf(name)
48         #os.unlink(name)
49
50         txt = txt.replace('\\\n', '')
51
52         lst = txt.strip().split(':')
53         val = ":".join(lst[1:])
54         val = val.split()
55
56         nodes = []
57         bld = self.generator.bld
58
59         f = re.compile("^("+self.env.variant()+"|\.\.)[\\/](.*)$")
60         for x in val:
61                 if os.path.isabs(x):
62
63                         if not preproc.go_absolute:
64                                 continue
65
66                         lock.acquire()
67                         try:
68                                 node = bld.root.find_resource(x)
69                         finally:
70                                 lock.release()
71                 else:
72                         g = re.search(re_src, x)
73                         if g:
74                                 x = g.group(2)
75                                 lock.acquire()
76                                 try:
77                                         node = bld.bldnode.parent.find_resource(x)
78                                 finally:
79                                         lock.release()
80                         else:
81                                 g = re.search(f, x)
82                                 if g:
83                                         x = g.group(2)
84                                         lock.acquire()
85                                         try:
86                                                 node = bld.srcnode.find_resource(x)
87                                         finally:
88                                                 lock.release()
89
90                 if id(node) == id(self.inputs[0]):
91                         # ignore the source file, it is already in the dependencies
92                         # this way, successful config tests may be retrieved from the cache
93                         continue
94
95                 if not node:
96                         raise ValueError('could not find %r for %r' % (x, self))
97                 else:
98                         nodes.append(node)
99
100         Logs.debug('deps: real scanner for %s returned %s' % (str(self), str(nodes)))
101
102         bld.node_deps[self.unique_id()] = nodes
103         bld.raw_deps[self.unique_id()] = []
104
105         try:
106                 del self.cache_sig
107         except:
108                 pass
109
110         Task.Task.post_run(self)
111
112 import Constants, Utils
113 def sig_implicit_deps(self):
114         try:
115                 return Task.Task.sig_implicit_deps(self)
116         except Utils.WafError:
117                 return Constants.SIG_NIL
118
119 for name in 'cc cxx'.split():
120         try:
121                 cls = Task.TaskBase.classes[name]
122         except KeyError:
123                 pass
124         else:
125                 cls.post_run = post_run
126                 cls.scan = scan
127                 cls.sig_implicit_deps = sig_implicit_deps