• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "gn/resolved_target_data.h"
6 
7 #include "gn/test_with_scope.h"
8 #include "util/test/test.h"
9 
10 // Tests that lib[_dir]s are inherited across deps boundaries for static
11 // libraries but not executables.
TEST(ResolvedTargetDataTest,LibInheritance)12 TEST(ResolvedTargetDataTest, LibInheritance) {
13   TestWithScope setup;
14   Err err;
15 
16   ResolvedTargetData resolved;
17 
18   const LibFile lib("foo");
19   const SourceDir libdir("/foo_dir/");
20 
21   // Leaf target with ldflags set.
22   TestTarget z(setup, "//foo:z", Target::STATIC_LIBRARY);
23   z.config_values().libs().push_back(lib);
24   z.config_values().lib_dirs().push_back(libdir);
25   ASSERT_TRUE(z.OnResolved(&err));
26 
27   // All lib[_dir]s should be set when target is resolved.
28   auto z_info = resolved.GetLibInfo(&z);
29   ASSERT_EQ(1u, z_info.all_libs.size());
30   EXPECT_EQ(lib, z_info.all_libs[0]);
31   ASSERT_EQ(1u, z_info.all_lib_dirs.size());
32   EXPECT_EQ(libdir, z_info.all_lib_dirs[0]);
33 
34   // Shared library target should inherit the libs from the static library
35   // and its own. Its own flag should be before the inherited one.
36   const LibFile second_lib("bar");
37   const SourceDir second_libdir("/bar_dir/");
38   TestTarget shared(setup, "//foo:shared", Target::SHARED_LIBRARY);
39   shared.config_values().libs().push_back(second_lib);
40   shared.config_values().lib_dirs().push_back(second_libdir);
41   shared.private_deps().push_back(LabelTargetPair(&z));
42   ASSERT_TRUE(shared.OnResolved(&err));
43 
44   const auto libinfo = resolved.GetLibInfo(&shared);
45   ASSERT_EQ(2u, libinfo.all_libs.size());
46   EXPECT_EQ(second_lib, libinfo.all_libs[0]);
47   EXPECT_EQ(lib, libinfo.all_libs[1]);
48   ASSERT_EQ(2u, libinfo.all_lib_dirs.size());
49   EXPECT_EQ(second_libdir, libinfo.all_lib_dirs[0]);
50   EXPECT_EQ(libdir, libinfo.all_lib_dirs[1]);
51 
52   // Executable target shouldn't get either by depending on shared.
53   TestTarget exec(setup, "//foo:exec", Target::EXECUTABLE);
54   exec.private_deps().push_back(LabelTargetPair(&shared));
55   ASSERT_TRUE(exec.OnResolved(&err));
56   auto exec_libinfo = resolved.GetLibInfo(&exec);
57   EXPECT_EQ(0u, exec_libinfo.all_libs.size());
58   EXPECT_EQ(0u, exec_libinfo.all_lib_dirs.size());
59 }
60 
61 // Tests that framework[_dir]s are inherited across deps boundaries for static
62 // libraries but not executables.
TEST(ResolvedTargetDataTest,FrameworkInheritance)63 TEST(ResolvedTargetDataTest, FrameworkInheritance) {
64   TestWithScope setup;
65   Err err;
66 
67   const std::string framework("Foo.framework");
68   const SourceDir frameworkdir("//out/foo/");
69 
70   // Leaf target with ldflags set.
71   TestTarget z(setup, "//foo:z", Target::STATIC_LIBRARY);
72   z.config_values().frameworks().push_back(framework);
73   z.config_values().framework_dirs().push_back(frameworkdir);
74   ASSERT_TRUE(z.OnResolved(&err));
75 
76   ResolvedTargetData resolved;
77 
78   // All framework[_dir]s should be set when target is resolved.
79   auto info = resolved.GetFrameworkInfo(&z);
80   ASSERT_EQ(1u, info.all_frameworks.size());
81   EXPECT_EQ(framework, info.all_frameworks[0]);
82   ASSERT_EQ(1u, info.all_framework_dirs.size());
83   EXPECT_EQ(frameworkdir, info.all_framework_dirs[0]);
84 
85   // Shared library target should inherit the libs from the static library
86   // and its own. Its own flag should be before the inherited one.
87   const std::string second_framework("Bar.framework");
88   const SourceDir second_frameworkdir("//out/bar/");
89   TestTarget shared(setup, "//foo:shared", Target::SHARED_LIBRARY);
90   shared.config_values().frameworks().push_back(second_framework);
91   shared.config_values().framework_dirs().push_back(second_frameworkdir);
92   shared.private_deps().push_back(LabelTargetPair(&z));
93   ASSERT_TRUE(shared.OnResolved(&err));
94 
95   auto shared_info = resolved.GetFrameworkInfo(&shared);
96   ASSERT_EQ(2u, shared_info.all_frameworks.size());
97   EXPECT_EQ(second_framework, shared_info.all_frameworks[0]);
98   EXPECT_EQ(framework, shared_info.all_frameworks[1]);
99   ASSERT_EQ(2u, shared_info.all_framework_dirs.size());
100   EXPECT_EQ(second_frameworkdir, shared_info.all_framework_dirs[0]);
101   EXPECT_EQ(frameworkdir, shared_info.all_framework_dirs[1]);
102 
103   // Executable target shouldn't get either by depending on shared.
104   TestTarget exec(setup, "//foo:exec", Target::EXECUTABLE);
105   exec.private_deps().push_back(LabelTargetPair(&shared));
106   ASSERT_TRUE(exec.OnResolved(&err));
107   auto exec_info = resolved.GetFrameworkInfo(&exec);
108   EXPECT_EQ(0u, exec_info.all_frameworks.size());
109   EXPECT_EQ(0u, exec_info.all_framework_dirs.size());
110 }
111 
TEST(ResolvedTargetDataTest,InheritLibs)112 TEST(ResolvedTargetDataTest, InheritLibs) {
113   TestWithScope setup;
114   Err err;
115 
116   // Create a dependency chain:
117   //   A (executable) -> B (shared lib) -> C (static lib) -> D (source set)
118   TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
119   TestTarget b(setup, "//foo:b", Target::SHARED_LIBRARY);
120   TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
121   TestTarget d(setup, "//foo:d", Target::SOURCE_SET);
122   a.private_deps().push_back(LabelTargetPair(&b));
123   b.private_deps().push_back(LabelTargetPair(&c));
124   c.private_deps().push_back(LabelTargetPair(&d));
125 
126   ASSERT_TRUE(d.OnResolved(&err));
127   ASSERT_TRUE(c.OnResolved(&err));
128   ASSERT_TRUE(b.OnResolved(&err));
129   ASSERT_TRUE(a.OnResolved(&err));
130 
131   ResolvedTargetData resolved;
132 
133   // C should have D in its inherited libs.
134   auto c_inherited_libs = resolved.inherited_libraries(&c);
135   ASSERT_EQ(1u, c_inherited_libs.size());
136   EXPECT_EQ(&d, c_inherited_libs[0].target());
137 
138   // B should have C and D in its inherited libs.
139   auto b_inherited = resolved.inherited_libraries(&b);
140   ASSERT_EQ(2u, b_inherited.size());
141   EXPECT_EQ(&c, b_inherited[0].target());
142   EXPECT_EQ(&d, b_inherited[1].target());
143 
144   // A should have B in its inherited libs, but not any others (the shared
145   // library will include the static library and source set).
146   auto a_inherited = resolved.inherited_libraries(&a);
147   ASSERT_EQ(1u, a_inherited.size());
148   EXPECT_EQ(&b, a_inherited[0].target());
149 }
150 
TEST(ResolvedTargetData,NoActionDepPropgation)151 TEST(ResolvedTargetData, NoActionDepPropgation) {
152   TestWithScope setup;
153   Err err;
154   ResolvedTargetData resolved;
155   // Create a dependency chain:
156   //   A (exe) -> B (action) -> C (source_set)
157   {
158     TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
159     TestTarget b(setup, "//foo:b", Target::ACTION);
160     TestTarget c(setup, "//foo:c", Target::SOURCE_SET);
161 
162     a.private_deps().push_back(LabelTargetPair(&b));
163     b.private_deps().push_back(LabelTargetPair(&c));
164 
165     ASSERT_TRUE(c.OnResolved(&err));
166     ASSERT_TRUE(b.OnResolved(&err));
167     ASSERT_TRUE(a.OnResolved(&err));
168 
169     // The executable should not have inherited the source set across the
170     // action.
171     ASSERT_TRUE(resolved.inherited_libraries(&a).empty());
172   }
173 }
174 
TEST(ResolvedTargetDataTest,InheritCompleteStaticLib)175 TEST(ResolvedTargetDataTest, InheritCompleteStaticLib) {
176   TestWithScope setup;
177   Err err;
178 
179   ResolvedTargetData resolved;
180 
181   // Create a dependency chain:
182   //   A (executable) -> B (complete static lib) -> C (source set)
183   TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
184   TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
185   b.set_complete_static_lib(true);
186 
187   const LibFile lib("foo");
188   const SourceDir lib_dir("/foo_dir/");
189   TestTarget c(setup, "//foo:c", Target::SOURCE_SET);
190   c.config_values().libs().push_back(lib);
191   c.config_values().lib_dirs().push_back(lib_dir);
192 
193   a.public_deps().push_back(LabelTargetPair(&b));
194   b.public_deps().push_back(LabelTargetPair(&c));
195 
196   ASSERT_TRUE(c.OnResolved(&err));
197   ASSERT_TRUE(b.OnResolved(&err));
198   ASSERT_TRUE(a.OnResolved(&err));
199 
200   // B should have C in its inherited libs.
201   auto b_inherited = resolved.inherited_libraries(&b);
202   ASSERT_EQ(1u, b_inherited.size());
203   EXPECT_EQ(&c, b_inherited[0].target());
204 
205   // A should have B in its inherited libs, but not any others (the complete
206   // static library will include the source set).
207   auto a_inherited = resolved.inherited_libraries(&a);
208   ASSERT_EQ(1u, a_inherited.size());
209   EXPECT_EQ(&b, a_inherited[0].target());
210 
211   // A should inherit the libs and lib_dirs from the C.
212   auto a_info = resolved.GetLibInfo(&a);
213   ASSERT_EQ(1u, a_info.all_libs.size());
214   EXPECT_EQ(lib, a_info.all_libs[0]);
215   ASSERT_EQ(1u, a_info.all_lib_dirs.size());
216   EXPECT_EQ(lib_dir, a_info.all_lib_dirs[0]);
217 }
218 
TEST(ResolvedTargetDataTest,InheritCompleteStaticLibStaticLibDeps)219 TEST(ResolvedTargetDataTest, InheritCompleteStaticLibStaticLibDeps) {
220   TestWithScope setup;
221   Err err;
222 
223   // Create a dependency chain:
224   //   A (executable) -> B (complete static lib) -> C (static lib)
225   TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
226   TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
227   b.set_complete_static_lib(true);
228   TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
229   a.public_deps().push_back(LabelTargetPair(&b));
230   b.public_deps().push_back(LabelTargetPair(&c));
231 
232   ASSERT_TRUE(c.OnResolved(&err));
233   ASSERT_TRUE(b.OnResolved(&err));
234   ASSERT_TRUE(a.OnResolved(&err));
235 
236   ResolvedTargetData resolved;
237 
238   // B should have C in its inherited libs.
239   auto b_inherited = resolved.inherited_libraries(&b);
240   ASSERT_EQ(1u, b_inherited.size());
241   EXPECT_EQ(&c, b_inherited[0].target());
242 
243   // A should have B in its inherited libs, but not any others (the complete
244   // static library will include the static library).
245   auto a_inherited = resolved.inherited_libraries(&a);
246   ASSERT_EQ(1u, a_inherited.size());
247   EXPECT_EQ(&b, a_inherited[0].target());
248 }
249 
TEST(ResolvedTargetDataTest,InheritCompleteStaticLibInheritedCompleteStaticLibDeps)250 TEST(ResolvedTargetDataTest,
251      InheritCompleteStaticLibInheritedCompleteStaticLibDeps) {
252   TestWithScope setup;
253   Err err;
254 
255   // Create a dependency chain:
256   //   A (executable) -> B (complete static lib) -> C (complete static lib)
257   TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
258   TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
259   b.set_complete_static_lib(true);
260   TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
261   c.set_complete_static_lib(true);
262 
263   a.private_deps().push_back(LabelTargetPair(&b));
264   b.private_deps().push_back(LabelTargetPair(&c));
265 
266   ASSERT_TRUE(c.OnResolved(&err));
267   ASSERT_TRUE(b.OnResolved(&err));
268   ASSERT_TRUE(a.OnResolved(&err));
269 
270   ResolvedTargetData resolved;
271 
272   // B should have C in its inherited libs.
273   auto b_inherited = resolved.inherited_libraries(&b);
274   ASSERT_EQ(1u, b_inherited.size());
275   EXPECT_EQ(&c, b_inherited[0].target());
276 
277   // A should have B and C in its inherited libs.
278   auto a_inherited = resolved.inherited_libraries(&a);
279   ASSERT_EQ(2u, a_inherited.size());
280   EXPECT_EQ(&b, a_inherited[0].target());
281   EXPECT_EQ(&c, a_inherited[1].target());
282 }
283 
TEST(ResolvedTargetDataTest,NoActionDepPropgation)284 TEST(ResolvedTargetDataTest, NoActionDepPropgation) {
285   TestWithScope setup;
286   Err err;
287   ResolvedTargetData resolved;
288 
289   // Create a dependency chain:
290   //   A (exe) -> B (action) -> C (source_set)
291   {
292     TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
293     TestTarget b(setup, "//foo:b", Target::ACTION);
294     TestTarget c(setup, "//foo:c", Target::SOURCE_SET);
295 
296     a.private_deps().push_back(LabelTargetPair(&b));
297     b.private_deps().push_back(LabelTargetPair(&c));
298 
299     ASSERT_TRUE(c.OnResolved(&err));
300     ASSERT_TRUE(b.OnResolved(&err));
301     ASSERT_TRUE(a.OnResolved(&err));
302 
303     // The executable should not have inherited the source set across the
304     // action.
305     auto libs = resolved.inherited_libraries(&a);
306     ASSERT_TRUE(libs.empty());
307   }
308 }
309