summaryrefslogtreecommitdiff
path: root/buildtools/wafsamba/gccdeps.py
blob: bd03da4f8b00ccba74dc6f730789d4033efcf172 (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
#!/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

lock = threading.Lock()


def detect(conf):
	conf.env.append_unique('CCFLAGS', '-MD')

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_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 = name.rstrip('.o') + '.d'
	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)

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