]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/test/dependency_test.py
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / tools / build / test / dependency_test.py
CommitLineData
7c673cae
FG
1#!/usr/bin/python
2
3# Copyright 2003 Dave Abrahams
4# Copyright 2002, 2003, 2005, 2006 Vladimir Prus
5# Distributed under the Boost Software License, Version 1.0.
1e59de90
TL
6# (See accompanying file LICENSE.txt or copy at
7# https://www.bfgroup.xyz/b2/LICENSE.txt)
7c673cae
FG
8
9import BoostBuild
10
11
12def test_basic():
11fdf7f2 13 t = BoostBuild.Tester(["-d3", "-d+12"], use_test_config=False)
7c673cae
FG
14
15 t.write("a.cpp", """
16#include <a.h>
17# include "a.h"
18#include <x.h>
19int main() {}
20""")
21 t.write("a.h", "\n")
22 t.write("a_c.c", """\
23#include <a.h>
24# include "a.h"
25#include <x.h>
26""")
27 t.write("b.cpp", """\
28#include "a.h"
29int main() {}
30""")
31 t.write("b.h", "\n")
32 t.write("c.cpp", """\
33#include "x.h"
34int main() {}
35""")
36 t.write("e.cpp", """\
37#include "x.h"
38int main() {}
39""")
40 t.write("x.foo", "")
41 t.write("y.foo", "")
42
43 t.write("src1/a.h", '#include "b.h"\n')
44 t.write("src1/b.h", '#include "c.h"\n')
45 t.write("src1/c.h", "\n")
46 t.write("src1/z.h", """\
47extern int dummy_variable_suppressing_empty_file_warning_on_hp_cxx_compiler;
48""")
49
50 t.write("src2/b.h", "\n")
51
52 t.write("jamroot.jam", """\
53import foo ;
54import types/cpp ;
55import types/exe ;
56
57project test : requirements <include>src1 ;
58
59exe a : x.foo a.cpp a_c.c ;
60exe b : b.cpp ;
61
62# Because of <define>FOO, c.cpp will be compiled to a different directory than
63# everything for main target "a". Therefore, without <implicit-dependency>, C
64# preprocessor processing that module will not find "x.h", which is part of
65# "a"'s dependency graph.
66#
67# --------------------------
68# More detailed explanation:
69# --------------------------
70# c.cpp includes x.h which does not exist on the current include path so Boost
71# Jam will try to match it to existing Jam targets to cover cases as this one
72# where the file is generated by the same build.
73#
74# However, as x.h is not part of "c" metatarget's dependency graph, Boost
75# Build will not actualize its target by default, i.e. create its Jam target.
76#
77# To get the Jam target created in time, we use the <implicit-dependency>
78# feature. This tells Boost Build that it needs to actualize the dependency
79# graph for metatarget "a", even though that metatarget has not been directly
80# mentioned and is not a dependency for any of the metatargets mentioned in the
81# current build request.
82#
83# Note that Boost Build does not automatically add a dependency between the
84# Jam targets in question so, if Boost Jam does not add a dependency on a target
85# from that other dependency graph (x.h in our case), i.e. if c.cpp does not
86# actually include x.h, us actualizing it will have no effect in the end as
87# Boost Jam will not have a reason to actually build those targets in spite of
88# knowing about them.
89exe c : c.cpp : <define>FOO <implicit-dependency>a ;
90""")
91
92 t.write("foo.jam", """\
93import generators ;
94import modules ;
95import os ;
96import print ;
97import type ;
98import types/cpp ;
99
100type.register FOO : foo ;
101
102generators.register-standard foo.foo : FOO : CPP H ;
103
104nl = "
105" ;
106
107rule foo ( targets * : sources * : properties * )
108{
109 # On NT, you need an exported symbol in order to have an import library
110 # generated. We will not really use the symbol defined here, just force the
111 # import library creation.
112 if ( [ os.name ] = NT || [ modules.peek : OS ] in CYGWIN ) &&
113 <main-target-type>LIB in $(properties)
114 {
115 .decl = "void __declspec(dllexport) foo() {}" ;
116 }
117 print.output $(<[1]) ;
118 print.text $(.decl:E="//")$(nl) ;
119 print.output $(<[2]) ;
120 print.text "#include <z.h>"$(nl) ;
121}
122""")
123
124 t.write("foo.py",
125r"""import bjam
126import b2.build.type as type
127import b2.build.generators as generators
128
129from b2.manager import get_manager
130
131type.register("FOO", ["foo"])
132generators.register_standard("foo.foo", ["FOO"], ["CPP", "H"])
133
134def prepare_foo(targets, sources, properties):
135 if properties.get('os') in ['windows', 'cygwin']:
136 bjam.call('set-target-variable', targets, "DECL",
137 "void __declspec(dllexport) foo() {}")
138
139get_manager().engine().register_action("foo.foo",
140 "echo -e $(DECL:E=//)\\n > $(<[1])\n"
141 "echo -e "#include <z.h>\\n" > $(<[2])\n", function=prepare_foo)
142""")
143
144 # Check that main target 'c' was able to find 'x.h' from 'a's dependency
145 # graph.
146 t.run_build_system()
b32b8144 147 t.expect_addition("bin/$toolset/debug*/c.exe")
7c673cae
FG
148
149 # Check handling of first level includes.
150
151 # Both 'a' and 'b' include "a.h" and should be updated.
152 t.touch("a.h")
153 t.run_build_system()
154
b32b8144
FG
155 t.expect_touch("bin/$toolset/debug*/a.exe")
156 t.expect_touch("bin/$toolset/debug*/a.obj")
157 t.expect_touch("bin/$toolset/debug*/a_c.obj")
158 t.expect_touch("bin/$toolset/debug*/b.exe")
159 t.expect_touch("bin/$toolset/debug*/b.obj")
20effc67
TL
160 t.ignore_touch("bin/*/a.rsp")
161 t.ignore_touch("bin/*/b.rsp")
7c673cae
FG
162 t.expect_nothing_more()
163
164 # Only source files using include <a.h> should be compiled.
165 t.touch("src1/a.h")
166 t.run_build_system()
167
b32b8144
FG
168 t.expect_touch("bin/$toolset/debug*/a.exe")
169 t.expect_touch("bin/$toolset/debug*/a.obj")
170 t.expect_touch("bin/$toolset/debug*/a_c.obj")
20effc67 171 t.ignore_touch("bin/*/a.rsp")
7c673cae
FG
172 t.expect_nothing_more()
173
174 # "src/a.h" includes "b.h" (in the same dir).
175 t.touch("src1/b.h")
176 t.run_build_system()
b32b8144
FG
177 t.expect_touch("bin/$toolset/debug*/a.exe")
178 t.expect_touch("bin/$toolset/debug*/a.obj")
179 t.expect_touch("bin/$toolset/debug*/a_c.obj")
20effc67 180 t.ignore_touch("bin/*/a.rsp")
7c673cae
FG
181 t.expect_nothing_more()
182
183 # Included by "src/b.h". We had a bug: file included using double quotes
184 # (e.g. "b.h") was not scanned at all in this case.
185 t.touch("src1/c.h")
186 t.run_build_system()
b32b8144 187 t.expect_touch("bin/$toolset/debug*/a.exe")
7c673cae
FG
188
189 t.touch("b.h")
190 t.run_build_system()
191 t.expect_nothing_more()
192
193 # Test dependency on a generated header.
194 #
195 # TODO: we have also to check that generated header is found correctly if
196 # it is different for different subvariants. Lacking any toolset support,
197 # this check will be implemented later.
198 t.touch("x.foo")
199 t.run_build_system()
b32b8144
FG
200 t.expect_touch("bin/$toolset/debug*/a.obj")
201 t.expect_touch("bin/$toolset/debug*/a_c.obj")
7c673cae
FG
202
203 # Check that generated headers are scanned for dependencies as well.
204 t.touch("src1/z.h")
205 t.run_build_system()
b32b8144
FG
206 t.expect_touch("bin/$toolset/debug*/a.obj")
207 t.expect_touch("bin/$toolset/debug*/a_c.obj")
7c673cae
FG
208
209 t.cleanup()
210
211
212def test_scanned_includes_with_absolute_paths():
213 """
214 Regression test: on Windows, <includes> with absolute paths were not
215 considered when scanning dependencies.
216
217 """
11fdf7f2 218 t = BoostBuild.Tester(["-d3", "-d+12"])
7c673cae
FG
219
220 t.write("jamroot.jam", """\
221path-constant TOP : . ;
222exe app : main.cpp : <include>$(TOP)/include ;
223""");
224
225 t.write("main.cpp", """\
226#include <dir/header.h>
227int main() {}
228""")
229
230 t.write("include/dir/header.h", "\n")
231
232 t.run_build_system()
b32b8144 233 t.expect_addition("bin/$toolset/debug*/main.obj")
7c673cae
FG
234
235 t.touch("include/dir/header.h")
236 t.run_build_system()
b32b8144 237 t.expect_touch("bin/$toolset/debug*/main.obj")
7c673cae
FG
238
239 t.cleanup()
240
241
242test_basic()
243test_scanned_includes_with_absolute_paths()