OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "testing/gtest/include/gtest/gtest.h" | 5 #include "testing/gtest/include/gtest/gtest.h" |
6 #include "tools/gn/build_settings.h" | 6 #include "tools/gn/build_settings.h" |
7 #include "tools/gn/config.h" | 7 #include "tools/gn/config.h" |
8 #include "tools/gn/settings.h" | 8 #include "tools/gn/settings.h" |
9 #include "tools/gn/target.h" | 9 #include "tools/gn/target.h" |
10 #include "tools/gn/test_with_scope.h" | 10 #include "tools/gn/test_with_scope.h" |
11 #include "tools/gn/toolchain.h" | 11 #include "tools/gn/toolchain.h" |
12 | 12 |
13 // Tests that depending on a group is like depending directly on the group's | 13 // Tests that depending on a group is like depending directly on the group's |
14 // deps. | 14 // deps. |
15 TEST(Target, GroupDeps) { | 15 TEST(Target, GroupDeps) { |
16 TestWithScope setup; | 16 TestWithScope setup; |
| 17 Err err; |
| 18 |
| 19 // Used as the origin for the not-automatically-set deps. |
| 20 IdentifierNode origin; |
17 | 21 |
18 // Two low-level targets. | 22 // Two low-level targets. |
19 Target x(setup.settings(), Label(SourceDir("//component/"), "x")); | 23 Target x(setup.settings(), Label(SourceDir("//component/"), "x")); |
20 x.set_output_type(Target::STATIC_LIBRARY); | 24 x.set_output_type(Target::STATIC_LIBRARY); |
21 x.SetToolchain(setup.toolchain()); | 25 x.SetToolchain(setup.toolchain()); |
22 x.OnResolved(); | 26 ASSERT_TRUE(x.OnResolved(&err)); |
23 Target y(setup.settings(), Label(SourceDir("//component/"), "y")); | 27 Target y(setup.settings(), Label(SourceDir("//component/"), "y")); |
24 y.set_output_type(Target::STATIC_LIBRARY); | 28 y.set_output_type(Target::STATIC_LIBRARY); |
25 y.SetToolchain(setup.toolchain()); | 29 y.SetToolchain(setup.toolchain()); |
26 y.OnResolved(); | 30 ASSERT_TRUE(y.OnResolved(&err)); |
27 | 31 |
28 // Make a group for both x and y. | 32 // Make a group for both x and y. |
29 Target g(setup.settings(), Label(SourceDir("//group/"), "g")); | 33 Target g(setup.settings(), Label(SourceDir("//group/"), "g")); |
30 g.set_output_type(Target::GROUP); | 34 g.set_output_type(Target::GROUP); |
| 35 g.visibility().SetPublic(); |
31 g.deps().push_back(LabelTargetPair(&x)); | 36 g.deps().push_back(LabelTargetPair(&x)); |
| 37 g.deps()[0].origin = &origin; |
32 g.deps().push_back(LabelTargetPair(&y)); | 38 g.deps().push_back(LabelTargetPair(&y)); |
| 39 g.deps()[1].origin = &origin; |
33 | 40 |
34 // Random placeholder target so we can see the group's deps get inserted at | 41 // Random placeholder target so we can see the group's deps get inserted at |
35 // the right place. | 42 // the right place. |
36 Target b(setup.settings(), Label(SourceDir("//app/"), "b")); | 43 Target b(setup.settings(), Label(SourceDir("//app/"), "b")); |
37 b.set_output_type(Target::STATIC_LIBRARY); | 44 b.set_output_type(Target::STATIC_LIBRARY); |
38 b.SetToolchain(setup.toolchain()); | 45 b.SetToolchain(setup.toolchain()); |
39 b.OnResolved(); | 46 b.visibility().SetPublic(); |
| 47 ASSERT_TRUE(b.OnResolved(&err)); |
40 | 48 |
41 // Make a target depending on the group and "b". OnResolved will expand. | 49 // Make a target depending on the group and "b". OnResolved will expand. |
42 Target a(setup.settings(), Label(SourceDir("//app/"), "a")); | 50 Target a(setup.settings(), Label(SourceDir("//app/"), "a")); |
43 a.set_output_type(Target::EXECUTABLE); | 51 a.set_output_type(Target::EXECUTABLE); |
44 a.deps().push_back(LabelTargetPair(&g)); | 52 a.deps().push_back(LabelTargetPair(&g)); |
| 53 a.deps()[0].origin = &origin; |
45 a.deps().push_back(LabelTargetPair(&b)); | 54 a.deps().push_back(LabelTargetPair(&b)); |
| 55 a.deps()[1].origin = &origin; |
46 a.SetToolchain(setup.toolchain()); | 56 a.SetToolchain(setup.toolchain()); |
47 a.OnResolved(); | 57 ASSERT_TRUE(a.OnResolved(&err)); |
48 | 58 |
49 // The group's deps should be inserted after the group itself in the deps | 59 // The group's deps should be inserted after the group itself in the deps |
50 // list, so we should get "g, x, y, b" | 60 // list, so we should get "g, x, y, b" |
51 ASSERT_EQ(4u, a.deps().size()); | 61 ASSERT_EQ(4u, a.deps().size()); |
52 EXPECT_EQ(&g, a.deps()[0].ptr); | 62 EXPECT_EQ(&g, a.deps()[0].ptr); |
53 EXPECT_EQ(&x, a.deps()[1].ptr); | 63 EXPECT_EQ(&x, a.deps()[1].ptr); |
54 EXPECT_EQ(&y, a.deps()[2].ptr); | 64 EXPECT_EQ(&y, a.deps()[2].ptr); |
55 EXPECT_EQ(&b, a.deps()[3].ptr); | 65 EXPECT_EQ(&b, a.deps()[3].ptr); |
| 66 |
| 67 // The "regular" deps on a should have the origin set. The automatically |
| 68 // expanded ones will have a null origin so we know they are generated. |
| 69 EXPECT_EQ(&origin, a.deps()[0].origin); |
| 70 EXPECT_EQ(NULL, a.deps()[1].origin); |
| 71 EXPECT_EQ(NULL, a.deps()[2].origin); |
| 72 EXPECT_EQ(&origin, a.deps()[3].origin); |
56 } | 73 } |
57 | 74 |
58 // Tests that lib[_dir]s are inherited across deps boundaries for static | 75 // Tests that lib[_dir]s are inherited across deps boundaries for static |
59 // libraries but not executables. | 76 // libraries but not executables. |
60 TEST(Target, LibInheritance) { | 77 TEST(Target, LibInheritance) { |
61 TestWithScope setup; | 78 TestWithScope setup; |
| 79 Err err; |
62 | 80 |
63 const std::string lib("foo"); | 81 const std::string lib("foo"); |
64 const SourceDir libdir("/foo_dir/"); | 82 const SourceDir libdir("/foo_dir/"); |
65 | 83 |
66 // Leaf target with ldflags set. | 84 // Leaf target with ldflags set. |
67 Target z(setup.settings(), Label(SourceDir("//foo/"), "z")); | 85 Target z(setup.settings(), Label(SourceDir("//foo/"), "z")); |
68 z.set_output_type(Target::STATIC_LIBRARY); | 86 z.set_output_type(Target::STATIC_LIBRARY); |
69 z.config_values().libs().push_back(lib); | 87 z.config_values().libs().push_back(lib); |
70 z.config_values().lib_dirs().push_back(libdir); | 88 z.config_values().lib_dirs().push_back(libdir); |
71 z.SetToolchain(setup.toolchain()); | 89 z.SetToolchain(setup.toolchain()); |
72 z.OnResolved(); | 90 ASSERT_TRUE(z.OnResolved(&err)); |
73 | 91 |
74 // All lib[_dir]s should be set when target is resolved. | 92 // All lib[_dir]s should be set when target is resolved. |
75 ASSERT_EQ(1u, z.all_libs().size()); | 93 ASSERT_EQ(1u, z.all_libs().size()); |
76 EXPECT_EQ(lib, z.all_libs()[0]); | 94 EXPECT_EQ(lib, z.all_libs()[0]); |
77 ASSERT_EQ(1u, z.all_lib_dirs().size()); | 95 ASSERT_EQ(1u, z.all_lib_dirs().size()); |
78 EXPECT_EQ(libdir, z.all_lib_dirs()[0]); | 96 EXPECT_EQ(libdir, z.all_lib_dirs()[0]); |
79 | 97 |
80 // Shared library target should inherit the libs from the static library | 98 // Shared library target should inherit the libs from the static library |
81 // and its own. Its own flag should be before the inherited one. | 99 // and its own. Its own flag should be before the inherited one. |
82 const std::string second_lib("bar"); | 100 const std::string second_lib("bar"); |
83 const SourceDir second_libdir("/bar_dir/"); | 101 const SourceDir second_libdir("/bar_dir/"); |
84 Target shared(setup.settings(), Label(SourceDir("//foo/"), "shared")); | 102 Target shared(setup.settings(), Label(SourceDir("//foo/"), "shared")); |
85 shared.set_output_type(Target::SHARED_LIBRARY); | 103 shared.set_output_type(Target::SHARED_LIBRARY); |
86 shared.config_values().libs().push_back(second_lib); | 104 shared.config_values().libs().push_back(second_lib); |
87 shared.config_values().lib_dirs().push_back(second_libdir); | 105 shared.config_values().lib_dirs().push_back(second_libdir); |
88 shared.deps().push_back(LabelTargetPair(&z)); | 106 shared.deps().push_back(LabelTargetPair(&z)); |
89 shared.SetToolchain(setup.toolchain()); | 107 shared.SetToolchain(setup.toolchain()); |
90 shared.OnResolved(); | 108 ASSERT_TRUE(shared.OnResolved(&err)); |
91 | 109 |
92 ASSERT_EQ(2u, shared.all_libs().size()); | 110 ASSERT_EQ(2u, shared.all_libs().size()); |
93 EXPECT_EQ(second_lib, shared.all_libs()[0]); | 111 EXPECT_EQ(second_lib, shared.all_libs()[0]); |
94 EXPECT_EQ(lib, shared.all_libs()[1]); | 112 EXPECT_EQ(lib, shared.all_libs()[1]); |
95 ASSERT_EQ(2u, shared.all_lib_dirs().size()); | 113 ASSERT_EQ(2u, shared.all_lib_dirs().size()); |
96 EXPECT_EQ(second_libdir, shared.all_lib_dirs()[0]); | 114 EXPECT_EQ(second_libdir, shared.all_lib_dirs()[0]); |
97 EXPECT_EQ(libdir, shared.all_lib_dirs()[1]); | 115 EXPECT_EQ(libdir, shared.all_lib_dirs()[1]); |
98 | 116 |
99 // Executable target shouldn't get either by depending on shared. | 117 // Executable target shouldn't get either by depending on shared. |
100 Target exec(setup.settings(), Label(SourceDir("//foo/"), "exec")); | 118 Target exec(setup.settings(), Label(SourceDir("//foo/"), "exec")); |
101 exec.set_output_type(Target::EXECUTABLE); | 119 exec.set_output_type(Target::EXECUTABLE); |
102 exec.deps().push_back(LabelTargetPair(&shared)); | 120 exec.deps().push_back(LabelTargetPair(&shared)); |
103 exec.SetToolchain(setup.toolchain()); | 121 exec.SetToolchain(setup.toolchain()); |
104 exec.OnResolved(); | 122 ASSERT_TRUE(exec.OnResolved(&err)); |
105 EXPECT_EQ(0u, exec.all_libs().size()); | 123 EXPECT_EQ(0u, exec.all_libs().size()); |
106 EXPECT_EQ(0u, exec.all_lib_dirs().size()); | 124 EXPECT_EQ(0u, exec.all_lib_dirs().size()); |
107 } | 125 } |
108 | 126 |
109 // Test all/direct_dependent_configs inheritance, and | 127 // Test all/direct_dependent_configs inheritance, and |
110 // forward_dependent_configs_from | 128 // forward_dependent_configs_from |
111 TEST(Target, DependentConfigs) { | 129 TEST(Target, DependentConfigs) { |
112 TestWithScope setup; | 130 TestWithScope setup; |
| 131 Err err; |
113 | 132 |
114 // Set up a dependency chain of a -> b -> c | 133 // Set up a dependency chain of a -> b -> c |
115 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); | 134 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); |
116 a.set_output_type(Target::EXECUTABLE); | 135 a.set_output_type(Target::EXECUTABLE); |
117 a.SetToolchain(setup.toolchain()); | 136 a.SetToolchain(setup.toolchain()); |
118 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); | 137 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); |
119 b.set_output_type(Target::STATIC_LIBRARY); | 138 b.set_output_type(Target::STATIC_LIBRARY); |
120 b.SetToolchain(setup.toolchain()); | 139 b.SetToolchain(setup.toolchain()); |
121 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); | 140 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); |
122 c.set_output_type(Target::STATIC_LIBRARY); | 141 c.set_output_type(Target::STATIC_LIBRARY); |
123 c.SetToolchain(setup.toolchain()); | 142 c.SetToolchain(setup.toolchain()); |
124 a.deps().push_back(LabelTargetPair(&b)); | 143 a.deps().push_back(LabelTargetPair(&b)); |
125 b.deps().push_back(LabelTargetPair(&c)); | 144 b.deps().push_back(LabelTargetPair(&c)); |
126 | 145 |
127 // Normal non-inherited config. | 146 // Normal non-inherited config. |
128 Config config(setup.settings(), Label(SourceDir("//foo/"), "config")); | 147 Config config(setup.settings(), Label(SourceDir("//foo/"), "config")); |
129 c.configs().push_back(LabelConfigPair(&config)); | 148 c.configs().push_back(LabelConfigPair(&config)); |
130 | 149 |
131 // All dependent config. | 150 // All dependent config. |
132 Config all(setup.settings(), Label(SourceDir("//foo/"), "all")); | 151 Config all(setup.settings(), Label(SourceDir("//foo/"), "all")); |
133 c.all_dependent_configs().push_back(LabelConfigPair(&all)); | 152 c.all_dependent_configs().push_back(LabelConfigPair(&all)); |
134 | 153 |
135 // Direct dependent config. | 154 // Direct dependent config. |
136 Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct")); | 155 Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct")); |
137 c.direct_dependent_configs().push_back(LabelConfigPair(&direct)); | 156 c.direct_dependent_configs().push_back(LabelConfigPair(&direct)); |
138 | 157 |
139 c.OnResolved(); | 158 ASSERT_TRUE(c.OnResolved(&err)); |
140 b.OnResolved(); | 159 ASSERT_TRUE(b.OnResolved(&err)); |
141 a.OnResolved(); | 160 ASSERT_TRUE(a.OnResolved(&err)); |
142 | 161 |
143 // B should have gotten both dependent configs from C. | 162 // B should have gotten both dependent configs from C. |
144 ASSERT_EQ(2u, b.configs().size()); | 163 ASSERT_EQ(2u, b.configs().size()); |
145 EXPECT_EQ(&all, b.configs()[0].ptr); | 164 EXPECT_EQ(&all, b.configs()[0].ptr); |
146 EXPECT_EQ(&direct, b.configs()[1].ptr); | 165 EXPECT_EQ(&direct, b.configs()[1].ptr); |
147 ASSERT_EQ(1u, b.all_dependent_configs().size()); | 166 ASSERT_EQ(1u, b.all_dependent_configs().size()); |
148 EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr); | 167 EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr); |
149 | 168 |
150 // A should have just gotten the "all" dependent config from C. | 169 // A should have just gotten the "all" dependent config from C. |
151 ASSERT_EQ(1u, a.configs().size()); | 170 ASSERT_EQ(1u, a.configs().size()); |
152 EXPECT_EQ(&all, a.configs()[0].ptr); | 171 EXPECT_EQ(&all, a.configs()[0].ptr); |
153 EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr); | 172 EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr); |
154 | 173 |
155 // Making an an alternate A and B with B forwarding the direct dependents. | 174 // Making an an alternate A and B with B forwarding the direct dependents. |
156 Target a_fwd(setup.settings(), Label(SourceDir("//foo/"), "a_fwd")); | 175 Target a_fwd(setup.settings(), Label(SourceDir("//foo/"), "a_fwd")); |
157 a_fwd.set_output_type(Target::EXECUTABLE); | 176 a_fwd.set_output_type(Target::EXECUTABLE); |
158 a_fwd.SetToolchain(setup.toolchain()); | 177 a_fwd.SetToolchain(setup.toolchain()); |
159 Target b_fwd(setup.settings(), Label(SourceDir("//foo/"), "b_fwd")); | 178 Target b_fwd(setup.settings(), Label(SourceDir("//foo/"), "b_fwd")); |
160 b_fwd.set_output_type(Target::STATIC_LIBRARY); | 179 b_fwd.set_output_type(Target::STATIC_LIBRARY); |
161 b_fwd.SetToolchain(setup.toolchain()); | 180 b_fwd.SetToolchain(setup.toolchain()); |
162 a_fwd.deps().push_back(LabelTargetPair(&b_fwd)); | 181 a_fwd.deps().push_back(LabelTargetPair(&b_fwd)); |
163 b_fwd.deps().push_back(LabelTargetPair(&c)); | 182 b_fwd.deps().push_back(LabelTargetPair(&c)); |
164 b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c)); | 183 b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c)); |
165 | 184 |
166 b_fwd.OnResolved(); | 185 ASSERT_TRUE(b_fwd.OnResolved(&err)); |
167 a_fwd.OnResolved(); | 186 ASSERT_TRUE(a_fwd.OnResolved(&err)); |
168 | 187 |
169 // A_fwd should now have both configs. | 188 // A_fwd should now have both configs. |
170 ASSERT_EQ(2u, a_fwd.configs().size()); | 189 ASSERT_EQ(2u, a_fwd.configs().size()); |
171 EXPECT_EQ(&all, a_fwd.configs()[0].ptr); | 190 EXPECT_EQ(&all, a_fwd.configs()[0].ptr); |
172 EXPECT_EQ(&direct, a_fwd.configs()[1].ptr); | 191 EXPECT_EQ(&direct, a_fwd.configs()[1].ptr); |
173 ASSERT_EQ(1u, a_fwd.all_dependent_configs().size()); | 192 ASSERT_EQ(1u, a_fwd.all_dependent_configs().size()); |
174 EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr); | 193 EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr); |
175 } | 194 } |
176 | 195 |
177 // Tests that forward_dependent_configs_from works for groups, forwarding the | 196 // Tests that forward_dependent_configs_from works for groups, forwarding the |
178 // group's deps' dependent configs. | 197 // group's deps' dependent configs. |
179 TEST(Target, ForwardDependentConfigsFromGroups) { | 198 TEST(Target, ForwardDependentConfigsFromGroups) { |
180 TestWithScope setup; | 199 TestWithScope setup; |
| 200 Err err; |
181 | 201 |
182 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); | 202 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); |
183 a.set_output_type(Target::EXECUTABLE); | 203 a.set_output_type(Target::EXECUTABLE); |
184 a.SetToolchain(setup.toolchain()); | 204 a.SetToolchain(setup.toolchain()); |
185 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); | 205 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); |
186 b.set_output_type(Target::GROUP); | 206 b.set_output_type(Target::GROUP); |
187 b.SetToolchain(setup.toolchain()); | 207 b.SetToolchain(setup.toolchain()); |
188 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); | 208 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); |
189 c.set_output_type(Target::STATIC_LIBRARY); | 209 c.set_output_type(Target::STATIC_LIBRARY); |
190 c.SetToolchain(setup.toolchain()); | 210 c.SetToolchain(setup.toolchain()); |
191 a.deps().push_back(LabelTargetPair(&b)); | 211 a.deps().push_back(LabelTargetPair(&b)); |
192 b.deps().push_back(LabelTargetPair(&c)); | 212 b.deps().push_back(LabelTargetPair(&c)); |
193 | 213 |
194 // Direct dependent config on C. | 214 // Direct dependent config on C. |
195 Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct")); | 215 Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct")); |
196 c.direct_dependent_configs().push_back(LabelConfigPair(&direct)); | 216 c.direct_dependent_configs().push_back(LabelConfigPair(&direct)); |
197 | 217 |
198 // A forwards the dependent configs from B. | 218 // A forwards the dependent configs from B. |
199 a.forward_dependent_configs().push_back(LabelTargetPair(&b)); | 219 a.forward_dependent_configs().push_back(LabelTargetPair(&b)); |
200 | 220 |
201 c.OnResolved(); | 221 ASSERT_TRUE(c.OnResolved(&err)); |
202 b.OnResolved(); | 222 ASSERT_TRUE(b.OnResolved(&err)); |
203 a.OnResolved(); | 223 ASSERT_TRUE(a.OnResolved(&err)); |
204 | 224 |
205 // The config should now be on A, and in A's direct dependent configs. | 225 // The config should now be on A, and in A's direct dependent configs. |
206 ASSERT_EQ(1u, a.configs().size()); | 226 ASSERT_EQ(1u, a.configs().size()); |
207 ASSERT_EQ(&direct, a.configs()[0].ptr); | 227 ASSERT_EQ(&direct, a.configs()[0].ptr); |
208 ASSERT_EQ(1u, a.direct_dependent_configs().size()); | 228 ASSERT_EQ(1u, a.direct_dependent_configs().size()); |
209 ASSERT_EQ(&direct, a.direct_dependent_configs()[0].ptr); | 229 ASSERT_EQ(&direct, a.direct_dependent_configs()[0].ptr); |
210 } | 230 } |
211 | 231 |
212 TEST(Target, InheritLibs) { | 232 TEST(Target, InheritLibs) { |
213 TestWithScope setup; | 233 TestWithScope setup; |
| 234 Err err; |
214 | 235 |
215 // Create a dependency chain: | 236 // Create a dependency chain: |
216 // A (executable) -> B (shared lib) -> C (static lib) -> D (source set) | 237 // A (executable) -> B (shared lib) -> C (static lib) -> D (source set) |
217 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); | 238 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); |
218 a.set_output_type(Target::EXECUTABLE); | 239 a.set_output_type(Target::EXECUTABLE); |
219 a.SetToolchain(setup.toolchain()); | 240 a.SetToolchain(setup.toolchain()); |
220 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); | 241 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); |
221 b.set_output_type(Target::SHARED_LIBRARY); | 242 b.set_output_type(Target::SHARED_LIBRARY); |
222 b.SetToolchain(setup.toolchain()); | 243 b.SetToolchain(setup.toolchain()); |
223 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); | 244 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); |
224 c.set_output_type(Target::STATIC_LIBRARY); | 245 c.set_output_type(Target::STATIC_LIBRARY); |
225 c.SetToolchain(setup.toolchain()); | 246 c.SetToolchain(setup.toolchain()); |
226 Target d(setup.settings(), Label(SourceDir("//foo/"), "d")); | 247 Target d(setup.settings(), Label(SourceDir("//foo/"), "d")); |
227 d.set_output_type(Target::SOURCE_SET); | 248 d.set_output_type(Target::SOURCE_SET); |
228 d.SetToolchain(setup.toolchain()); | 249 d.SetToolchain(setup.toolchain()); |
229 a.deps().push_back(LabelTargetPair(&b)); | 250 a.deps().push_back(LabelTargetPair(&b)); |
230 b.deps().push_back(LabelTargetPair(&c)); | 251 b.deps().push_back(LabelTargetPair(&c)); |
231 c.deps().push_back(LabelTargetPair(&d)); | 252 c.deps().push_back(LabelTargetPair(&d)); |
232 | 253 |
233 d.OnResolved(); | 254 ASSERT_TRUE(d.OnResolved(&err)); |
234 c.OnResolved(); | 255 ASSERT_TRUE(c.OnResolved(&err)); |
235 b.OnResolved(); | 256 ASSERT_TRUE(b.OnResolved(&err)); |
236 a.OnResolved(); | 257 ASSERT_TRUE(a.OnResolved(&err)); |
237 | 258 |
238 // C should have D in its inherited libs. | 259 // C should have D in its inherited libs. |
239 const UniqueVector<const Target*>& c_inherited = c.inherited_libraries(); | 260 const UniqueVector<const Target*>& c_inherited = c.inherited_libraries(); |
240 EXPECT_EQ(1u, c_inherited.size()); | 261 EXPECT_EQ(1u, c_inherited.size()); |
241 EXPECT_TRUE(c_inherited.IndexOf(&d) != static_cast<size_t>(-1)); | 262 EXPECT_TRUE(c_inherited.IndexOf(&d) != static_cast<size_t>(-1)); |
242 | 263 |
243 // B should have C and D in its inherited libs. | 264 // B should have C and D in its inherited libs. |
244 const UniqueVector<const Target*>& b_inherited = b.inherited_libraries(); | 265 const UniqueVector<const Target*>& b_inherited = b.inherited_libraries(); |
245 EXPECT_EQ(2u, b_inherited.size()); | 266 EXPECT_EQ(2u, b_inherited.size()); |
246 EXPECT_TRUE(b_inherited.IndexOf(&c) != static_cast<size_t>(-1)); | 267 EXPECT_TRUE(b_inherited.IndexOf(&c) != static_cast<size_t>(-1)); |
247 EXPECT_TRUE(b_inherited.IndexOf(&d) != static_cast<size_t>(-1)); | 268 EXPECT_TRUE(b_inherited.IndexOf(&d) != static_cast<size_t>(-1)); |
248 | 269 |
249 // A should have B in its inherited libs, but not any others (the shared | 270 // A should have B in its inherited libs, but not any others (the shared |
250 // library will include the static library and source set). | 271 // library will include the static library and source set). |
251 const UniqueVector<const Target*>& a_inherited = a.inherited_libraries(); | 272 const UniqueVector<const Target*>& a_inherited = a.inherited_libraries(); |
252 EXPECT_EQ(1u, a_inherited.size()); | 273 EXPECT_EQ(1u, a_inherited.size()); |
253 EXPECT_TRUE(a_inherited.IndexOf(&b) != static_cast<size_t>(-1)); | 274 EXPECT_TRUE(a_inherited.IndexOf(&b) != static_cast<size_t>(-1)); |
254 } | 275 } |
255 | 276 |
256 TEST(Target, GetComputedOutputName) { | 277 TEST(Target, GetComputedOutputName) { |
257 TestWithScope setup; | 278 TestWithScope setup; |
| 279 Err err; |
258 | 280 |
259 // Basic target with no prefix (executable type tool in the TestWithScope has | 281 // Basic target with no prefix (executable type tool in the TestWithScope has |
260 // no prefix) or output name. | 282 // no prefix) or output name. |
261 Target basic(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 283 Target basic(setup.settings(), Label(SourceDir("//foo/"), "bar")); |
262 basic.set_output_type(Target::EXECUTABLE); | 284 basic.set_output_type(Target::EXECUTABLE); |
263 basic.SetToolchain(setup.toolchain()); | 285 basic.SetToolchain(setup.toolchain()); |
264 basic.OnResolved(); | 286 ASSERT_TRUE(basic.OnResolved(&err)); |
265 EXPECT_EQ("bar", basic.GetComputedOutputName(false)); | 287 EXPECT_EQ("bar", basic.GetComputedOutputName(false)); |
266 EXPECT_EQ("bar", basic.GetComputedOutputName(true)); | 288 EXPECT_EQ("bar", basic.GetComputedOutputName(true)); |
267 | 289 |
268 // Target with no prefix but an output name. | 290 // Target with no prefix but an output name. |
269 Target with_name(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 291 Target with_name(setup.settings(), Label(SourceDir("//foo/"), "bar")); |
270 with_name.set_output_type(Target::EXECUTABLE); | 292 with_name.set_output_type(Target::EXECUTABLE); |
271 with_name.set_output_name("myoutput"); | 293 with_name.set_output_name("myoutput"); |
272 with_name.SetToolchain(setup.toolchain()); | 294 with_name.SetToolchain(setup.toolchain()); |
273 with_name.OnResolved(); | 295 ASSERT_TRUE(with_name.OnResolved(&err)); |
274 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false)); | 296 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false)); |
275 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true)); | 297 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true)); |
276 | 298 |
277 // Target with a "lib" prefix (the static library tool in the TestWithScope | 299 // Target with a "lib" prefix (the static library tool in the TestWithScope |
278 // should specify a "lib" output prefix). | 300 // should specify a "lib" output prefix). |
279 Target with_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 301 Target with_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar")); |
280 with_prefix.set_output_type(Target::STATIC_LIBRARY); | 302 with_prefix.set_output_type(Target::STATIC_LIBRARY); |
281 with_prefix.SetToolchain(setup.toolchain()); | 303 with_prefix.SetToolchain(setup.toolchain()); |
282 with_prefix.OnResolved(); | 304 ASSERT_TRUE(with_prefix.OnResolved(&err)); |
283 EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false)); | 305 EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false)); |
284 EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true)); | 306 EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true)); |
285 | 307 |
286 // Target with a "lib" prefix that already has it applied. The prefix should | 308 // Target with a "lib" prefix that already has it applied. The prefix should |
287 // not duplicate something already in the target name. | 309 // not duplicate something already in the target name. |
288 Target dup_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 310 Target dup_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar")); |
289 dup_prefix.set_output_type(Target::STATIC_LIBRARY); | 311 dup_prefix.set_output_type(Target::STATIC_LIBRARY); |
290 dup_prefix.set_output_name("libbar"); | 312 dup_prefix.set_output_name("libbar"); |
291 dup_prefix.SetToolchain(setup.toolchain()); | 313 dup_prefix.SetToolchain(setup.toolchain()); |
292 dup_prefix.OnResolved(); | 314 ASSERT_TRUE(dup_prefix.OnResolved(&err)); |
293 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false)); | 315 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false)); |
294 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true)); | 316 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true)); |
295 } | 317 } |
| 318 |
| 319 // Test visibility failure case. |
| 320 TEST(Target, VisibilityFails) { |
| 321 TestWithScope setup; |
| 322 Err err; |
| 323 |
| 324 Target b(setup.settings(), Label(SourceDir("//private/"), "b")); |
| 325 b.set_output_type(Target::STATIC_LIBRARY); |
| 326 b.SetToolchain(setup.toolchain()); |
| 327 b.visibility().SetPrivate(b.label().dir()); |
| 328 ASSERT_TRUE(b.OnResolved(&err)); |
| 329 |
| 330 // Make a target depending on "b". The dependency must have an origin to mark |
| 331 // it as user-set so we check visibility. This check should fail. |
| 332 Target a(setup.settings(), Label(SourceDir("//app/"), "a")); |
| 333 a.set_output_type(Target::EXECUTABLE); |
| 334 a.deps().push_back(LabelTargetPair(&b)); |
| 335 IdentifierNode origin; // Dummy origin. |
| 336 a.deps()[0].origin = &origin; |
| 337 a.SetToolchain(setup.toolchain()); |
| 338 ASSERT_FALSE(a.OnResolved(&err)); |
| 339 } |
| 340 |
| 341 // Tests that A -> Group -> B where the group is visible from A but B isn't, |
| 342 // passes visibility even though the group's deps get expanded into A. |
| 343 TEST(Target, VisibilityGroup) { |
| 344 TestWithScope setup; |
| 345 Err err; |
| 346 |
| 347 IdentifierNode origin; // Dummy origin. |
| 348 |
| 349 // B has private visibility. This lets the group see it since the group is in |
| 350 // the same directory. |
| 351 Target b(setup.settings(), Label(SourceDir("//private/"), "b")); |
| 352 b.set_output_type(Target::STATIC_LIBRARY); |
| 353 b.SetToolchain(setup.toolchain()); |
| 354 b.visibility().SetPrivate(b.label().dir()); |
| 355 ASSERT_TRUE(b.OnResolved(&err)); |
| 356 |
| 357 // The group has public visibility and depends on b. |
| 358 Target g(setup.settings(), Label(SourceDir("//private/"), "g")); |
| 359 g.set_output_type(Target::GROUP); |
| 360 g.SetToolchain(setup.toolchain()); |
| 361 g.deps().push_back(LabelTargetPair(&b)); |
| 362 g.deps()[0].origin = &origin; |
| 363 g.visibility().SetPublic(); |
| 364 ASSERT_TRUE(b.OnResolved(&err)); |
| 365 |
| 366 // Make a target depending on "g". This should succeed. |
| 367 Target a(setup.settings(), Label(SourceDir("//app/"), "a")); |
| 368 a.set_output_type(Target::EXECUTABLE); |
| 369 a.deps().push_back(LabelTargetPair(&g)); |
| 370 a.deps()[0].origin = &origin; |
| 371 a.SetToolchain(setup.toolchain()); |
| 372 ASSERT_TRUE(a.OnResolved(&err)); |
| 373 } |
| 374 |
| 375 // Verifies that only testonly targets can depend on other testonly targets. |
| 376 // Many of the above dependency checking cases covered the non-testonly |
| 377 // case. |
| 378 TEST(Target, Testonly) { |
| 379 TestWithScope setup; |
| 380 Err err; |
| 381 |
| 382 // "testlib" is a test-only library. |
| 383 Target testlib(setup.settings(), Label(SourceDir("//test/"), "testlib")); |
| 384 testlib.set_testonly(true); |
| 385 testlib.set_output_type(Target::STATIC_LIBRARY); |
| 386 testlib.SetToolchain(setup.toolchain()); |
| 387 ASSERT_TRUE(testlib.OnResolved(&err)); |
| 388 |
| 389 // "test" is a test-only executable depending on testlib, this is OK. |
| 390 Target test(setup.settings(), Label(SourceDir("//test/"), "test")); |
| 391 test.set_testonly(true); |
| 392 test.set_output_type(Target::EXECUTABLE); |
| 393 test.deps().push_back(LabelTargetPair(&testlib)); |
| 394 test.SetToolchain(setup.toolchain()); |
| 395 ASSERT_TRUE(test.OnResolved(&err)); |
| 396 |
| 397 // "product" is a non-test depending on testlib. This should fail. |
| 398 Target product(setup.settings(), Label(SourceDir("//app/"), "product")); |
| 399 product.set_testonly(false); |
| 400 product.set_output_type(Target::EXECUTABLE); |
| 401 product.deps().push_back(LabelTargetPair(&testlib)); |
| 402 product.SetToolchain(setup.toolchain()); |
| 403 ASSERT_FALSE(product.OnResolved(&err)); |
| 404 } |
OLD | NEW |