/
parsedepends.tar
102 lines (82 loc) · 10 KB
/
parsedepends.tar
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
parsedepends.in 0000644 0001750 0001750 00000006163 11000255101 013422 0 ustar ludwig ludwig <section>
<title>Using compiler generated dependency files</title>
<para>
&SCons; has built-in scanners for a number of languages. Sometimes these scanners
fail to extract certain implicit dependencies due to limitations of the scanner.
</para>
<scons_example name="macroinc">
<file name="hello.c" printme="1">
#define FOO_HEADER "foo.h"
#include FOO_HEADER
int main() {
return FOO;
}
</file>
<file name="SConstruct">
Program('hello', 'hello.c')
</file>
<file name="foo.h">
#define FOO 42
</file>
</scons_example>
<scons_output example="macroinc" os="posix">
<scons_output_command>scons -Q</scons_output_command>
<scons_output_command output=" [CHANGE CONTENTS OF foo.h]">edit foo.h</scons_output_command>
<scons_output_command>scons -Q</scons_output_command>
</scons_output>
<para>
Apparently, the scanner does not know about the header dependency.
The scanner is not able to expand the macro, as it is no full-fledged
C preprocessor.
</para>
<para>
In these cases, you may also use the compiler to extract the
implicit dependencies. &ParseDepends; can parse the contents of the compiler output
in the style of Make or mkdep, and explicitly establish all of the listed
dependencies.
</para>
<scons_example name="parsedep">
<file name="hello.c">
#define FOO_HEADER "foo.h"
#include FOO_HEADER
int main() {
return FOO;
}
</file>
<file name="SConstruct" printme="1">
obj = Object('hello.c', CCFLAGS = '-MD -MF hello.d')
SideEffect('hello.d', obj)
ParseDepends('hello.d')
Program('hello', obj)
</file>
<file name="foo.h">
#define FOO 42
</file>
</scons_example>
<scons_output example="parsedep" os="posix">
<scons_output_command>scons -Q</scons_output_command>
<scons_output_command output=" [CHANGE CONTENTS OF foo.h]">edit foo.h</scons_output_command>
<scons_output_command>scons -Q</scons_output_command>
</scons_output>
<para>
Parsing dependencies from a compiler-generated <filename>.d</filename> file has
a chicken-and-egg problem, that causes an unnecessary rebuild when
MD5 signatures are used.
</para>
<scons_output example="parsedep" os="posix">
<scons_output_command>scons -Q</scons_output_command>
<scons_output_command>scons -Q --debug=explain</scons_output_command>
</scons_output>
<para>
In the first pass, the dependency file is generated while the object
file is compiled. At that time, &SCons; does not know about the
dependency on <filename>foo.h</filename>. In the second pass, the object file is regenerated
because <filename>foo.h</filename> is detected as a new dependency.
</para>
<para>
This is a limitation of using MD5 signatures with compiler-generated
dependency files. Those unnecessary rebuilds can only be circumvented
by resorting to timestamp signatures.
</para>
</section>