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 12 namespace { 13 14 class 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. 35 TEST_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. 68 TEST_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 114 TEST_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