1#!/usr/local/bin/python3.8
2
3# Copyright 2003 Dave Abrahams
4# Copyright 2002, 2003, 2004 Vladimir Prus
5# Distributed under the Boost Software License, Version 1.0.
6# (See accompanying file LICENSE_1_0.txt or copy at
7# http://www.boost.org/LICENSE_1_0.txt)
8
9import BoostBuild
10
11def test_basic():
12    t = BoostBuild.Tester(use_test_config=False)
13
14    t.write("jamroot.jam", "lib a : a.cpp : <include>. ;")
15    t.write("a.cpp", """\
16#include <a.h>
17void
18# ifdef _WIN32
19__declspec(dllexport)
20# endif
21foo() {}
22""")
23    t.write("a.h", "//empty file\n")
24    t.write("d/jamfile.jam", "exe b : b.cpp ..//a ;")
25    t.write("d/b.cpp", """\
26void foo();
27int main() { foo(); }
28""")
29    t.run_build_system(subdir="d")
30
31    # Path features with condition.
32    t.write("jamroot.jam", "lib a : a.cpp : <variant>debug:<include>. ;")
33    t.rm("bin")
34    t.run_build_system(subdir="d")
35
36
37    # Path features with condition in usage requirements.
38    t.write("jamroot.jam", """\
39lib a : a.cpp : <include>. : : <variant>debug:<include>. ;
40""")
41    t.write("d/b.cpp", """\
42#include <a.h>
43void foo();
44int main() { foo(); }
45""")
46    t.rm("d/bin")
47    t.run_build_system(subdir="d")
48
49    t.cleanup()
50
51
52def test_absolute_paths():
53    """
54      Test that absolute paths inside requirements are ok. The problems
55    appeared only when building targets in subprojects.
56
57    """
58    t = BoostBuild.Tester(use_test_config=False)
59
60    t.write("jamroot.jam", "build-project x ;")
61    t.write("x/jamfile.jam", """\
62local pwd = [ PWD ] ;
63project : requirements <include>$(pwd)/x/include ;
64exe m : m.cpp : <include>$(pwd)/x/include2 ;
65""")
66    t.write("x/m.cpp", """\
67#include <h1.hpp>
68#include <h2.hpp>
69int main() {}
70""")
71    t.write("x/include/h1.hpp", "\n")
72    t.write("x/include2/h2.hpp", "\n")
73
74    t.run_build_system()
75    t.expect_addition("x/bin/$toolset/debug*/m.exe")
76
77    t.cleanup()
78
79
80def test_ordered_paths():
81    """Test that "&&" in path features is handled correctly."""
82
83    t = BoostBuild.Tester(use_test_config=False)
84
85    t.write("jamroot.jam", "build-project sub ;")
86    t.write("sub/jamfile.jam", "exe a : a.cpp : <include>../h1&&../h2 ;")
87    t.write("sub/a.cpp", """\
88#include <header.h>
89int main() { return OK; }
90""")
91    t.write("h2/header.h", "int const OK = 0;\n")
92    t.run_build_system()
93    t.expect_addition("sub/bin/$toolset/debug*/a.exe")
94
95    t.cleanup()
96
97
98def test_paths_set_by_indirect_conditionals():
99    t = BoostBuild.Tester(use_test_config=False)
100
101    header = "child_dir/folder_to_include/some_header.h"
102
103    t.write("jamroot.jam", """
104build-project child_dir ;
105rule attach-include-parent ( properties * )
106{
107    return <include>another_folder ;
108}
109# requirements inherited from a parent project will bind paths
110# relative to the project that actually names the rule.
111project : requirements <conditional>@attach-include-parent ;
112""")
113    t.write("child_dir/jamfile.jam", """\
114import remote/remote ;
115
116# If we set the <include>folder_to_include property directly, it will work
117obj x1 : x.cpp : <conditional>@attach-include-local ;
118obj x2 : x.cpp : <conditional>@remote.attach-include-remote ;
119
120rule attach-include-local ( properties * )
121{
122    return <include>folder_to_include ;
123}
124""")
125    t.write("child_dir/remote/remote.jam", """\
126rule attach-include-remote ( properties * )
127{
128    return <include>folder_to_include ;
129}
130""")
131    t.write("child_dir/x.cpp", """\
132#include <some_header.h>
133#include <header2.h>
134int main() {}
135""")
136    t.write(header, "int some_func();\n")
137    t.write("another_folder/header2.h", "int f2();\n")
138    t.write("child_dir/folder_to_include/jamfile.jam", "")
139
140    expected_x1 = "child_dir/bin/$toolset/debug*/x1.obj"
141    expected_x2 = "child_dir/bin/$toolset/debug*/x2.obj"
142
143    t.run_build_system()
144    t.expect_addition(expected_x1)
145    t.expect_addition(expected_x2)
146
147    t.touch(header)
148    t.run_build_system(subdir="child_dir")
149    t.expect_touch(expected_x1)
150    t.expect_touch(expected_x2)
151
152    t.touch(header)
153    t.run_build_system([".."], subdir="child_dir/folder_to_include")
154    t.expect_touch(expected_x1)
155    t.expect_touch(expected_x2)
156
157    t.cleanup()
158
159
160test_basic()
161test_absolute_paths()
162test_ordered_paths()
163test_paths_set_by_indirect_conditionals()
164