summaryrefslogtreecommitdiff
path: root/third_party/waf/wafadmin/3rdparty/gccdeps.py
blob: 55cd515b958ffd172f6038943810d358bb99ff9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2008-2010 (ita)

"""
Execute the tasks with gcc -MD, read the dependencies from the .d file
and prepare the dependency calculation for the next run
"""

import os, re, threading
import Task, Logs, Utils, preproc
from TaskGen import before, after, feature

lock = threading.Lock()

preprocessor_flag = '-MD'

@feature('cc', 'c')
@before('apply_core')
def add_mmd_cc(self):
	if self.env.get_flat('CCFLAGS').find(preprocessor_flag) < 0:
		self.env.append_value('CCFLAGS', preprocessor_flag)

@feature('cxx')
@before('apply_core')
def add_mmd_cxx(self):
	if self.env.get_flat('CXXFLAGS').find(preprocessor_flag) < 0:
		self.env.append_value('CXXFLAGS', preprocessor_flag)

def scan(self):
	"the scanner does not do anything initially"
	nodes = self.generator.bld.node_deps.get(self.unique_id(), [])
	names = []
	return (nodes, names)

re_o = re.compile("\.o$")
re_src = re.compile("^(\.\.)[\\/](.*)$")

def post_run(self):
	# The following code is executed by threads, it is not safe, so a lock is needed...

	if getattr(self, 'cached', None):
		return Task.Task.post_run(self)

	name = self.outputs[0].abspath(self.env)
	name = re_o.sub('.d', name)
	txt = Utils.readf(name)
	#os.unlink(name)

	txt = txt.replace('\\\n', '')

	lst = txt.strip().split(':')
	val = ":".join(lst[1:])
	val = val.split()

	nodes = []
	bld = self.generator.bld

	f = re.compile("^("+self.env.variant()+"|\.\.)[\\/](.*)$")
	for x in val:
		if os.path.isabs(x):

			if not preproc.go_absolute:
				continue

			lock.acquire()
			try:
				node = bld.root.find_resource(x)
			finally:
				lock.release()
		else:
			g = re.search(re_src, x)
			if g:
				x = g.group(2)
				lock.acquire()
				try:
					node = bld.bldnode.parent.find_resource(x)
				finally:
					lock.release()
			else:
				g = re.search(f, x)
				if g:
					x = g.group(2)
					lock.acquire()
					try:
						node = bld.srcnode.find_resource(x)
					finally:
						lock.release()

		if id(node) == id(self.inputs[0]):
			# ignore the source file, it is already in the dependencies
			# this way, successful config tests may be retrieved from the cache
			continue

		if not node:
			raise ValueError('could not find %r for %r' % (x, self))
		else:
			nodes.append(node)

	Logs.debug('deps: real scanner for %s returned %s' % (str(self), str(nodes)))

	bld.node_deps[self.unique_id()] = nodes
	bld.raw_deps[self.unique_id()] = []

	try:
		del self.cache_sig
	except:
		pass

	Task.Task.post_run(self)

import Constants, Utils
def sig_implicit_deps(self):
	try:
		return Task.Task.sig_implicit_deps(self)
	except Utils.WafError:
		return Constants.SIG_NIL

for name in 'cc cxx'.split():
	try:
		cls = Task.TaskBase.classes[name]
	except KeyError:
		pass
	else:
		cls.post_run = post_run
		cls.scan = scan
		cls.sig_implicit_deps = sig_implicit_deps