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