1#!/usr/local/bin/python3.8
2
3# Copyright (C) 2003. Vladimir Prus
4# Distributed under the Boost Software License, Version 1.0.
5# (See accompanying file LICENSE_1_0.txt or copy at
6# http://www.boost.org/LICENSE_1_0.txt)
7
8# Test the 'glob' rule in Jamfile context.
9
10import BoostBuild
11
12
13def test_basic():
14    t = BoostBuild.Tester(use_test_config=False)
15
16    t.write("jamroot.jam", "")
17    t.write("d1/a.cpp", "int main() {}\n")
18    t.write("d1/jamfile.jam", "exe a : [ glob *.cpp ] ../d2/d//l ;")
19    t.write("d2/d/l.cpp", """\
20#if defined(_WIN32)
21__declspec(dllexport)
22void force_import_lib_creation() {}
23#endif
24""")
25    t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;")
26    t.write("d3/d/jamfile.jam", "exe a : [ glob ../*.cpp ] ;")
27    t.write("d3/a.cpp", "int main() {}\n")
28
29    t.run_build_system(subdir="d1")
30    t.expect_addition("d1/bin/$toolset/debug*/a.exe")
31
32    t.run_build_system(subdir="d3/d")
33    t.expect_addition("d3/d/bin/$toolset/debug*/a.exe")
34
35    t.rm("d2/d/bin")
36    t.run_build_system(subdir="d2/d")
37    t.expect_addition("d2/d/bin/$toolset/debug*/l.dll")
38
39    t.cleanup()
40
41
42def test_source_location():
43    """
44      Test that when 'source-location' is explicitly-specified glob works
45    relative to the source location.
46
47    """
48    t = BoostBuild.Tester(use_test_config=False)
49
50    t.write("jamroot.jam", "")
51    t.write("d1/a.cpp", "very bad non-compilable file\n")
52    t.write("d1/src/a.cpp", "int main() {}\n")
53    t.write("d1/jamfile.jam", """\
54project : source-location src ;
55exe a : [ glob *.cpp ] ../d2/d//l ;
56""")
57    t.write("d2/d/l.cpp", """\
58#if defined(_WIN32)
59__declspec(dllexport)
60void force_import_lib_creation() {}
61#endif
62""")
63    t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;")
64
65    t.run_build_system(subdir="d1")
66    t.expect_addition("d1/bin/$toolset/debug*/a.exe")
67
68    t.cleanup()
69
70
71def test_wildcards_and_exclusion_patterns():
72    """
73        Test that wildcards can include directories. Also test exclusion
74     patterns.
75
76    """
77    t = BoostBuild.Tester(use_test_config=False)
78
79    t.write("jamroot.jam", "")
80    t.write("d1/src/foo/a.cpp", "void bar(); int main() { bar(); }\n")
81    t.write("d1/src/bar/b.cpp", "void bar() {}\n")
82    t.write("d1/src/bar/bad.cpp", "very bad non-compilable file\n")
83    t.write("d1/jamfile.jam", """\
84project : source-location src ;
85exe a : [ glob foo/*.cpp bar/*.cpp : bar/bad* ] ../d2/d//l ;
86""")
87    t.write("d2/d/l.cpp", """\
88#if defined(_WIN32)
89__declspec(dllexport)
90void force_import_lib_creation() {}
91#endif
92""")
93    t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;")
94
95    t.run_build_system(subdir="d1")
96    t.expect_addition("d1/bin/$toolset/debug*/a.exe")
97
98    t.cleanup()
99
100
101def test_glob_tree():
102    """Test that 'glob-tree' works."""
103
104    t = BoostBuild.Tester(use_test_config=False)
105
106    t.write("jamroot.jam", "")
107    t.write("d1/src/foo/a.cpp", "void bar(); int main() { bar(); }\n")
108    t.write("d1/src/bar/b.cpp", "void bar() {}\n")
109    t.write("d1/src/bar/bad.cpp", "very bad non-compilable file\n")
110    t.write("d1/jamfile.jam", """\
111project : source-location src ;
112exe a : [ glob-tree *.cpp : bad* ] ../d2/d//l ;
113""")
114    t.write("d2/d/l.cpp", """\
115#if defined(_WIN32)
116__declspec(dllexport)
117void force_import_lib_creation() {}
118#endif
119""")
120    t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;")
121
122    t.run_build_system(subdir="d1")
123    t.expect_addition("d1/bin/$toolset/debug*/a.exe")
124
125    t.cleanup()
126
127
128def test_directory_names_in_glob_tree():
129    """Test that directory names in patterns for 'glob-tree' are rejected."""
130
131    t = BoostBuild.Tester(use_test_config=False)
132
133    t.write("jamroot.jam", "")
134    t.write("d1/src/a.cpp", "very bad non-compilable file\n")
135    t.write("d1/src/foo/a.cpp", "void bar(); int main() { bar(); }\n")
136    t.write("d1/src/bar/b.cpp", "void bar() {}\n")
137    t.write("d1/src/bar/bad.cpp", "very bad non-compilable file\n")
138    t.write("d1/jamfile.jam", """\
139project : source-location src ;
140exe a : [ glob-tree foo/*.cpp bar/*.cpp : bad* ] ../d2/d//l ;
141""")
142    t.write("d2/d/l.cpp", """\
143#if defined(_WIN32)
144__declspec(dllexport)
145void force_import_lib_creation() {}
146#endif
147""")
148    t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;")
149
150    t.run_build_system(subdir="d1", status=1)
151    t.expect_output_lines("error: The patterns * may not include directory")
152
153    t.cleanup()
154
155
156def test_glob_with_absolute_names():
157    """Test that 'glob' works with absolute names."""
158
159    t = BoostBuild.Tester(use_test_config=False)
160
161    t.write("jamroot.jam", "")
162    t.write("d1/src/a.cpp", "very bad non-compilable file\n")
163    t.write("d1/src/foo/a.cpp", "void bar(); int main() { bar(); }\n")
164    t.write("d1/src/bar/b.cpp", "void bar() {}\n")
165    # Note that to get the current dir, we use bjam's PWD, not Python's
166    # os.getcwd(), because the former will always return a long path while the
167    # latter might return a short path, which would confuse path.glob.
168    t.write("d1/jamfile.jam", """\
169project : source-location src ;
170local pwd = [ PWD ] ;  # Always absolute.
171exe a : [ glob $(pwd)/src/foo/*.cpp $(pwd)/src/bar/*.cpp ] ../d2/d//l ;
172""")
173    t.write("d2/d/l.cpp", """\
174#if defined(_WIN32)
175__declspec(dllexport)
176void force_import_lib_creation() {}
177#endif
178""")
179    t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;")
180
181    t.run_build_system(subdir="d1")
182    t.expect_addition("d1/bin/$toolset/debug*/a.exe")
183
184    t.cleanup()
185
186
187def test_glob_excludes_in_subdirectory():
188    """
189      Regression test: glob excludes used to be broken when building from a
190    subdirectory.
191
192    """
193    t = BoostBuild.Tester(use_test_config=False)
194
195    t.write("jamroot.jam", "build-project p ;")
196    t.write("p/p.c", "int main() {}\n")
197    t.write("p/p_x.c", "very bad non-compilable file\n")
198    t.write("p/jamfile.jam", "exe p : [ glob *.c : p_x.c ] ;")
199
200    t.run_build_system(subdir="p")
201    t.expect_addition("p/bin/$toolset/debug*/p.exe")
202
203    t.cleanup()
204
205
206test_basic()
207test_source_location()
208test_wildcards_and_exclusion_patterns()
209test_glob_tree()
210test_directory_names_in_glob_tree()
211test_glob_with_absolute_names()
212test_glob_excludes_in_subdirectory()
213