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 3// found in the LICENSE file. 4 5#include "testing/gtest/include/gtest/gtest.h" 6#include "tools/gn/build_settings.h" 7#include "tools/gn/config.h" 8#include "tools/gn/settings.h" 9#include "tools/gn/target.h" 10#include "tools/gn/toolchain.h" 11 12namespace { 13 14class TargetTest : public testing::Test { 15 public: 16 TargetTest() 17 : build_settings_(), 18 settings_(&build_settings_, std::string()), 19 toolchain_(&settings_, Label(SourceDir("//tc/"), "tc")) { 20 settings_.set_toolchain_label(toolchain_.label()); 21 } 22 virtual ~TargetTest() { 23 } 24 25 protected: 26 BuildSettings build_settings_; 27 Settings settings_; 28 Toolchain toolchain_; 29}; 30 31} // namespace 32 33// Tests that depending on a group is like depending directly on the group's 34// deps. 35TEST_F(TargetTest, GroupDeps) { 36 // Two low-level targets. 37 Target x(&settings_, Label(SourceDir("//component/"), "x")); 38 Target y(&settings_, Label(SourceDir("//component/"), "y")); 39 40 // Make a group for both x and y. 41 Target g(&settings_, Label(SourceDir("//group/"), "g")); 42 g.set_output_type(Target::GROUP); 43 g.deps().push_back(LabelTargetPair(&x)); 44 g.deps().push_back(LabelTargetPair(&y)); 45 46 // Random placeholder target so we can see the group's deps get inserted at 47 // the right place. 48 Target b(&settings_, Label(SourceDir("//app/"), "b")); 49 50 // Make a target depending on the group and "b". OnResolved will expand. 51 Target a(&settings_, Label(SourceDir("//app/"), "a")); 52 a.set_output_type(Target::EXECUTABLE); 53 a.deps().push_back(LabelTargetPair(&g)); 54 a.deps().push_back(LabelTargetPair(&b)); 55 a.OnResolved(); 56 57 // The group's deps should be inserted after the group itself in the deps 58 // list, so we should get "g, x, y, b" 59 ASSERT_EQ(4u, a.deps().size()); 60 EXPECT_EQ(&g, a.deps()[0].ptr); 61 EXPECT_EQ(&x, a.deps()[1].ptr); 62 EXPECT_EQ(&y, a.deps()[2].ptr); 63 EXPECT_EQ(&b, a.deps()[3].ptr); 64} 65 66// Tests that lib[_dir]s are inherited across deps boundaries for static 67// libraries but not executables. 68TEST_F(TargetTest, LibInheritance) { 69 const std::string lib("foo"); 70 const SourceDir libdir("/foo_dir/"); 71 72 // Leaf target with ldflags set. 73 Target z(&settings_, Label(SourceDir("//foo/"), "z")); 74 z.set_output_type(Target::STATIC_LIBRARY); 75 z.config_values().libs().push_back(lib); 76 z.config_values().lib_dirs().push_back(libdir); 77 z.OnResolved(); 78 79 // All lib[_dir]s should be set when target is resolved. 80 ASSERT_EQ(1u, z.all_libs().size()); 81 EXPECT_EQ(lib, z.all_libs()[0]); 82 ASSERT_EQ(1u, z.all_lib_dirs().size()); 83 EXPECT_EQ(libdir, z.all_lib_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_lib("bar"); 88 const SourceDir second_libdir("/bar_dir/"); 89 Target shared(&settings_, Label(SourceDir("//foo/"), "shared")); 90 shared.set_output_type(Target::SHARED_LIBRARY); 91 shared.config_values().libs().push_back(second_lib); 92 shared.config_values().lib_dirs().push_back(second_libdir); 93 shared.deps().push_back(LabelTargetPair(&z)); 94 shared.OnResolved(); 95 96 ASSERT_EQ(2u, shared.all_libs().size()); 97 EXPECT_EQ(second_lib, shared.all_libs()[0]); 98 EXPECT_EQ(lib, shared.all_libs()[1]); 99 ASSERT_EQ(2u, shared.all_lib_dirs().size()); 100 EXPECT_EQ(second_libdir, shared.all_lib_dirs()[0]); 101 EXPECT_EQ(libdir, shared.all_lib_dirs()[1]); 102 103 // Executable target shouldn't get either by depending on shared. 104 Target exec(&settings_, Label(SourceDir("//foo/"), "exec")); 105 exec.set_output_type(Target::EXECUTABLE); 106 exec.deps().push_back(LabelTargetPair(&shared)); 107 exec.OnResolved(); 108 EXPECT_EQ(0u, exec.all_libs().size()); 109 EXPECT_EQ(0u, exec.all_lib_dirs().size()); 110} 111 112// Test all/direct_dependent_configs inheritance, and 113// forward_dependent_configs_from 114TEST_F(TargetTest, DependentConfigs) { 115 // Set up a dependency chain of a -> b -> c 116 Target a(&settings_, Label(SourceDir("//foo/"), "a")); 117 a.set_output_type(Target::EXECUTABLE); 118 Target b(&settings_, Label(SourceDir("//foo/"), "b")); 119 b.set_output_type(Target::STATIC_LIBRARY); 120 Target c(&settings_, Label(SourceDir("//foo/"), "c")); 121 c.set_output_type(Target::STATIC_LIBRARY); 122 a.deps().push_back(LabelTargetPair(&b)); 123 b.deps().push_back(LabelTargetPair(&c)); 124 125 // Normal non-inherited config. 126 Config config(&settings_, Label(SourceDir("//foo/"), "config")); 127 c.configs().push_back(LabelConfigPair(&config)); 128 129 // All dependent config. 130 Config all(&settings_, Label(SourceDir("//foo/"), "all")); 131 c.all_dependent_configs().push_back(LabelConfigPair(&all)); 132 133 // Direct dependent config. 134 Config direct(&settings_, Label(SourceDir("//foo/"), "direct")); 135 c.direct_dependent_configs().push_back(LabelConfigPair(&direct)); 136 137 c.OnResolved(); 138 b.OnResolved(); 139 a.OnResolved(); 140 141 // B should have gotten both dependent configs from C. 142 ASSERT_EQ(2u, b.configs().size()); 143 EXPECT_EQ(&all, b.configs()[0].ptr); 144 EXPECT_EQ(&direct, b.configs()[1].ptr); 145 ASSERT_EQ(1u, b.all_dependent_configs().size()); 146 EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr); 147 148 // A should have just gotten the "all" dependent config from C. 149 ASSERT_EQ(1u, a.configs().size()); 150 EXPECT_EQ(&all, a.configs()[0].ptr); 151 EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr); 152 153 // Making an an alternate A and B with B forwarding the direct dependents. 154 Target a_fwd(&settings_, Label(SourceDir("//foo/"), "a_fwd")); 155 a_fwd.set_output_type(Target::EXECUTABLE); 156 Target b_fwd(&settings_, Label(SourceDir("//foo/"), "b_fwd")); 157 b_fwd.set_output_type(Target::STATIC_LIBRARY); 158 a_fwd.deps().push_back(LabelTargetPair(&b_fwd)); 159 b_fwd.deps().push_back(LabelTargetPair(&c)); 160 b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c)); 161 162 b_fwd.OnResolved(); 163 a_fwd.OnResolved(); 164 165 // A_fwd should now have both configs. 166 ASSERT_EQ(2u, a_fwd.configs().size()); 167 EXPECT_EQ(&all, a_fwd.configs()[0].ptr); 168 EXPECT_EQ(&direct, a_fwd.configs()[1].ptr); 169 ASSERT_EQ(1u, a_fwd.all_dependent_configs().size()); 170 EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr); 171} 172 173// Tests that forward_dependent_configs_from works for groups, forwarding the 174// group's deps' dependent configs. 175TEST_F(TargetTest, ForwardDependentConfigsFromGroups) { 176 Target a(&settings_, Label(SourceDir("//foo/"), "a")); 177 a.set_output_type(Target::EXECUTABLE); 178 Target b(&settings_, Label(SourceDir("//foo/"), "b")); 179 b.set_output_type(Target::GROUP); 180 Target c(&settings_, Label(SourceDir("//foo/"), "c")); 181 c.set_output_type(Target::STATIC_LIBRARY); 182 a.deps().push_back(LabelTargetPair(&b)); 183 b.deps().push_back(LabelTargetPair(&c)); 184 185 // Direct dependent config on C. 186 Config direct(&settings_, Label(SourceDir("//foo/"), "direct")); 187 c.direct_dependent_configs().push_back(LabelConfigPair(&direct)); 188 189 // A forwards the dependent configs from B. 190 a.forward_dependent_configs().push_back(LabelTargetPair(&b)); 191 192 c.OnResolved(); 193 b.OnResolved(); 194 a.OnResolved(); 195 196 // The config should now be on A, and in A's direct dependent configs. 197 ASSERT_EQ(1u, a.configs().size()); 198 ASSERT_EQ(&direct, a.configs()[0].ptr); 199 ASSERT_EQ(1u, a.direct_dependent_configs().size()); 200 ASSERT_EQ(&direct, a.direct_dependent_configs()[0].ptr); 201} 202 203TEST_F(TargetTest, InheritLibs) { 204 // Create a dependency chain: 205 // A (executable) -> B (shared lib) -> C (static lib) -> D (source set) 206 Target a(&settings_, Label(SourceDir("//foo/"), "a")); 207 a.set_output_type(Target::EXECUTABLE); 208 Target b(&settings_, Label(SourceDir("//foo/"), "b")); 209 b.set_output_type(Target::SHARED_LIBRARY); 210 Target c(&settings_, Label(SourceDir("//foo/"), "c")); 211 c.set_output_type(Target::STATIC_LIBRARY); 212 Target d(&settings_, Label(SourceDir("//foo/"), "d")); 213 d.set_output_type(Target::SOURCE_SET); 214 a.deps().push_back(LabelTargetPair(&b)); 215 b.deps().push_back(LabelTargetPair(&c)); 216 c.deps().push_back(LabelTargetPair(&d)); 217 218 d.OnResolved(); 219 c.OnResolved(); 220 b.OnResolved(); 221 a.OnResolved(); 222 223 // C should have D in its inherited libs. 224 const std::set<const Target*>& c_inherited = c.inherited_libraries(); 225 EXPECT_EQ(1u, c_inherited.size()); 226 EXPECT_TRUE(c_inherited.find(&d) != c_inherited.end()); 227 228 // B should have C and D in its inherited libs. 229 const std::set<const Target*>& b_inherited = b.inherited_libraries(); 230 EXPECT_EQ(2u, b_inherited.size()); 231 EXPECT_TRUE(b_inherited.find(&c) != b_inherited.end()); 232 EXPECT_TRUE(b_inherited.find(&d) != b_inherited.end()); 233 234 // A should have B in its inherited libs, but not any others (the shared 235 // library will include the static library and source set). 236 const std::set<const Target*>& a_inherited = a.inherited_libraries(); 237 EXPECT_EQ(1u, a_inherited.size()); 238 EXPECT_TRUE(a_inherited.find(&b) != a_inherited.end()); 239} 240