| 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/scheduler.h" |
| 8 #include "tools/gn/settings.h" | 9 #include "tools/gn/settings.h" |
| 9 #include "tools/gn/target.h" | 10 #include "tools/gn/target.h" |
| 10 #include "tools/gn/test_with_scope.h" | 11 #include "tools/gn/test_with_scope.h" |
| 11 #include "tools/gn/toolchain.h" | 12 #include "tools/gn/toolchain.h" |
| 12 | 13 |
| 14 namespace { |
| 15 |
| 16 // Asserts that the current global scheduler has a single unknown generated |
| 17 // file with the given name from the given target. |
| 18 void AssertSchedulerHasOneUnknownFileMatching(const Target* target, |
| 19 const SourceFile& file) { |
| 20 auto unknown = g_scheduler->GetUnknownGeneratedInputs(); |
| 21 ASSERT_EQ(1u, unknown.size()); // Should be one unknown file. |
| 22 auto found = unknown.find(file); |
| 23 ASSERT_TRUE(found != unknown.end()) << file.value(); |
| 24 EXPECT_TRUE(target == found->second) |
| 25 << "Target doesn't match. Expected\n " |
| 26 << target->label().GetUserVisibleName(false) |
| 27 << "\nBut got\n " << found->second->label().GetUserVisibleName(false); |
| 28 } |
| 29 |
| 30 } // namespace |
| 31 |
| 13 // Tests that lib[_dir]s are inherited across deps boundaries for static | 32 // Tests that lib[_dir]s are inherited across deps boundaries for static |
| 14 // libraries but not executables. | 33 // libraries but not executables. |
| 15 TEST(Target, LibInheritance) { | 34 TEST(Target, LibInheritance) { |
| 16 TestWithScope setup; | 35 TestWithScope setup; |
| 17 Err err; | 36 Err err; |
| 18 | 37 |
| 19 const std::string lib("foo"); | 38 const std::string lib("foo"); |
| 20 const SourceDir libdir("/foo_dir/"); | 39 const SourceDir libdir("/foo_dir/"); |
| 21 | 40 |
| 22 // Leaf target with ldflags set. | 41 // Leaf target with ldflags set. |
| 23 Target z(setup.settings(), Label(SourceDir("//foo/"), "z")); | 42 TestTarget z(setup, "//foo:z", Target::STATIC_LIBRARY); |
| 24 z.set_output_type(Target::STATIC_LIBRARY); | |
| 25 z.config_values().libs().push_back(lib); | 43 z.config_values().libs().push_back(lib); |
| 26 z.config_values().lib_dirs().push_back(libdir); | 44 z.config_values().lib_dirs().push_back(libdir); |
| 27 z.visibility().SetPublic(); | |
| 28 z.SetToolchain(setup.toolchain()); | |
| 29 ASSERT_TRUE(z.OnResolved(&err)); | 45 ASSERT_TRUE(z.OnResolved(&err)); |
| 30 | 46 |
| 31 // All lib[_dir]s should be set when target is resolved. | 47 // All lib[_dir]s should be set when target is resolved. |
| 32 ASSERT_EQ(1u, z.all_libs().size()); | 48 ASSERT_EQ(1u, z.all_libs().size()); |
| 33 EXPECT_EQ(lib, z.all_libs()[0]); | 49 EXPECT_EQ(lib, z.all_libs()[0]); |
| 34 ASSERT_EQ(1u, z.all_lib_dirs().size()); | 50 ASSERT_EQ(1u, z.all_lib_dirs().size()); |
| 35 EXPECT_EQ(libdir, z.all_lib_dirs()[0]); | 51 EXPECT_EQ(libdir, z.all_lib_dirs()[0]); |
| 36 | 52 |
| 37 // Shared library target should inherit the libs from the static library | 53 // Shared library target should inherit the libs from the static library |
| 38 // and its own. Its own flag should be before the inherited one. | 54 // and its own. Its own flag should be before the inherited one. |
| 39 const std::string second_lib("bar"); | 55 const std::string second_lib("bar"); |
| 40 const SourceDir second_libdir("/bar_dir/"); | 56 const SourceDir second_libdir("/bar_dir/"); |
| 41 Target shared(setup.settings(), Label(SourceDir("//foo/"), "shared")); | 57 TestTarget shared(setup, "//foo:shared", Target::SHARED_LIBRARY); |
| 42 shared.set_output_type(Target::SHARED_LIBRARY); | |
| 43 shared.config_values().libs().push_back(second_lib); | 58 shared.config_values().libs().push_back(second_lib); |
| 44 shared.config_values().lib_dirs().push_back(second_libdir); | 59 shared.config_values().lib_dirs().push_back(second_libdir); |
| 45 shared.private_deps().push_back(LabelTargetPair(&z)); | 60 shared.private_deps().push_back(LabelTargetPair(&z)); |
| 46 shared.visibility().SetPublic(); | |
| 47 shared.SetToolchain(setup.toolchain()); | |
| 48 ASSERT_TRUE(shared.OnResolved(&err)); | 61 ASSERT_TRUE(shared.OnResolved(&err)); |
| 49 | 62 |
| 50 ASSERT_EQ(2u, shared.all_libs().size()); | 63 ASSERT_EQ(2u, shared.all_libs().size()); |
| 51 EXPECT_EQ(second_lib, shared.all_libs()[0]); | 64 EXPECT_EQ(second_lib, shared.all_libs()[0]); |
| 52 EXPECT_EQ(lib, shared.all_libs()[1]); | 65 EXPECT_EQ(lib, shared.all_libs()[1]); |
| 53 ASSERT_EQ(2u, shared.all_lib_dirs().size()); | 66 ASSERT_EQ(2u, shared.all_lib_dirs().size()); |
| 54 EXPECT_EQ(second_libdir, shared.all_lib_dirs()[0]); | 67 EXPECT_EQ(second_libdir, shared.all_lib_dirs()[0]); |
| 55 EXPECT_EQ(libdir, shared.all_lib_dirs()[1]); | 68 EXPECT_EQ(libdir, shared.all_lib_dirs()[1]); |
| 56 | 69 |
| 57 // Executable target shouldn't get either by depending on shared. | 70 // Executable target shouldn't get either by depending on shared. |
| 58 Target exec(setup.settings(), Label(SourceDir("//foo/"), "exec")); | 71 TestTarget exec(setup, "//foo:exec", Target::EXECUTABLE); |
| 59 exec.set_output_type(Target::EXECUTABLE); | |
| 60 exec.private_deps().push_back(LabelTargetPair(&shared)); | 72 exec.private_deps().push_back(LabelTargetPair(&shared)); |
| 61 exec.SetToolchain(setup.toolchain()); | |
| 62 ASSERT_TRUE(exec.OnResolved(&err)); | 73 ASSERT_TRUE(exec.OnResolved(&err)); |
| 63 EXPECT_EQ(0u, exec.all_libs().size()); | 74 EXPECT_EQ(0u, exec.all_libs().size()); |
| 64 EXPECT_EQ(0u, exec.all_lib_dirs().size()); | 75 EXPECT_EQ(0u, exec.all_lib_dirs().size()); |
| 65 } | 76 } |
| 66 | 77 |
| 67 // Test all_dependent_configs, public_config inheritance, and | 78 // Test all_dependent_configs, public_config inheritance, and |
| 68 // forward_dependent_configs_from | 79 // forward_dependent_configs_from |
| 69 TEST(Target, DependentConfigs) { | 80 TEST(Target, DependentConfigs) { |
| 70 TestWithScope setup; | 81 TestWithScope setup; |
| 71 Err err; | 82 Err err; |
| 72 | 83 |
| 73 // Set up a dependency chain of a -> b -> c | 84 // Set up a dependency chain of a -> b -> c |
| 74 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); | 85 TestTarget a(setup, "//foo:a", Target::EXECUTABLE); |
| 75 a.set_output_type(Target::EXECUTABLE); | 86 TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY); |
| 76 a.visibility().SetPublic(); | 87 TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY); |
| 77 a.SetToolchain(setup.toolchain()); | |
| 78 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); | |
| 79 b.set_output_type(Target::STATIC_LIBRARY); | |
| 80 b.visibility().SetPublic(); | |
| 81 b.SetToolchain(setup.toolchain()); | |
| 82 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); | |
| 83 c.set_output_type(Target::STATIC_LIBRARY); | |
| 84 c.visibility().SetPublic(); | |
| 85 c.SetToolchain(setup.toolchain()); | |
| 86 a.private_deps().push_back(LabelTargetPair(&b)); | 88 a.private_deps().push_back(LabelTargetPair(&b)); |
| 87 b.private_deps().push_back(LabelTargetPair(&c)); | 89 b.private_deps().push_back(LabelTargetPair(&c)); |
| 88 | 90 |
| 89 // Normal non-inherited config. | 91 // Normal non-inherited config. |
| 90 Config config(setup.settings(), Label(SourceDir("//foo/"), "config")); | 92 Config config(setup.settings(), Label(SourceDir("//foo/"), "config")); |
| 91 c.configs().push_back(LabelConfigPair(&config)); | 93 c.configs().push_back(LabelConfigPair(&config)); |
| 92 | 94 |
| 93 // All dependent config. | 95 // All dependent config. |
| 94 Config all(setup.settings(), Label(SourceDir("//foo/"), "all")); | 96 Config all(setup.settings(), Label(SourceDir("//foo/"), "all")); |
| 95 c.all_dependent_configs().push_back(LabelConfigPair(&all)); | 97 c.all_dependent_configs().push_back(LabelConfigPair(&all)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 108 EXPECT_EQ(&direct, b.configs()[1].ptr); | 110 EXPECT_EQ(&direct, b.configs()[1].ptr); |
| 109 ASSERT_EQ(1u, b.all_dependent_configs().size()); | 111 ASSERT_EQ(1u, b.all_dependent_configs().size()); |
| 110 EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr); | 112 EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr); |
| 111 | 113 |
| 112 // A should have just gotten the "all" dependent config from C. | 114 // A should have just gotten the "all" dependent config from C. |
| 113 ASSERT_EQ(1u, a.configs().size()); | 115 ASSERT_EQ(1u, a.configs().size()); |
| 114 EXPECT_EQ(&all, a.configs()[0].ptr); | 116 EXPECT_EQ(&all, a.configs()[0].ptr); |
| 115 EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr); | 117 EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr); |
| 116 | 118 |
| 117 // Making an an alternate A and B with B forwarding the direct dependents. | 119 // Making an an alternate A and B with B forwarding the direct dependents. |
| 118 Target a_fwd(setup.settings(), Label(SourceDir("//foo/"), "a_fwd")); | 120 TestTarget a_fwd(setup, "//foo:a_fwd", Target::EXECUTABLE); |
| 119 a_fwd.set_output_type(Target::EXECUTABLE); | 121 TestTarget b_fwd(setup, "//foo:b_fwd", Target::STATIC_LIBRARY); |
| 120 a_fwd.visibility().SetPublic(); | |
| 121 a_fwd.SetToolchain(setup.toolchain()); | |
| 122 Target b_fwd(setup.settings(), Label(SourceDir("//foo/"), "b_fwd")); | |
| 123 b_fwd.set_output_type(Target::STATIC_LIBRARY); | |
| 124 b_fwd.SetToolchain(setup.toolchain()); | |
| 125 b_fwd.visibility().SetPublic(); | |
| 126 a_fwd.private_deps().push_back(LabelTargetPair(&b_fwd)); | 122 a_fwd.private_deps().push_back(LabelTargetPair(&b_fwd)); |
| 127 b_fwd.private_deps().push_back(LabelTargetPair(&c)); | 123 b_fwd.private_deps().push_back(LabelTargetPair(&c)); |
| 128 b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c)); | 124 b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c)); |
| 129 | 125 |
| 130 ASSERT_TRUE(b_fwd.OnResolved(&err)); | 126 ASSERT_TRUE(b_fwd.OnResolved(&err)); |
| 131 ASSERT_TRUE(a_fwd.OnResolved(&err)); | 127 ASSERT_TRUE(a_fwd.OnResolved(&err)); |
| 132 | 128 |
| 133 // A_fwd should now have both configs. | 129 // A_fwd should now have both configs. |
| 134 ASSERT_EQ(2u, a_fwd.configs().size()); | 130 ASSERT_EQ(2u, a_fwd.configs().size()); |
| 135 EXPECT_EQ(&all, a_fwd.configs()[0].ptr); | 131 EXPECT_EQ(&all, a_fwd.configs()[0].ptr); |
| 136 EXPECT_EQ(&direct, a_fwd.configs()[1].ptr); | 132 EXPECT_EQ(&direct, a_fwd.configs()[1].ptr); |
| 137 ASSERT_EQ(1u, a_fwd.all_dependent_configs().size()); | 133 ASSERT_EQ(1u, a_fwd.all_dependent_configs().size()); |
| 138 EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr); | 134 EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr); |
| 139 } | 135 } |
| 140 | 136 |
| 141 TEST(Target, InheritLibs) { | 137 TEST(Target, InheritLibs) { |
| 142 TestWithScope setup; | 138 TestWithScope setup; |
| 143 Err err; | 139 Err err; |
| 144 | 140 |
| 145 // Create a dependency chain: | 141 // Create a dependency chain: |
| 146 // A (executable) -> B (shared lib) -> C (static lib) -> D (source set) | 142 // A (executable) -> B (shared lib) -> C (static lib) -> D (source set) |
| 147 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); | 143 TestTarget a(setup, "//foo:a", Target::EXECUTABLE); |
| 148 a.set_output_type(Target::EXECUTABLE); | 144 TestTarget b(setup, "//foo:b", Target::SHARED_LIBRARY); |
| 149 a.visibility().SetPublic(); | 145 TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY); |
| 150 a.SetToolchain(setup.toolchain()); | 146 TestTarget d(setup, "//foo:d", Target::SOURCE_SET); |
| 151 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); | |
| 152 b.set_output_type(Target::SHARED_LIBRARY); | |
| 153 b.visibility().SetPublic(); | |
| 154 b.SetToolchain(setup.toolchain()); | |
| 155 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); | |
| 156 c.set_output_type(Target::STATIC_LIBRARY); | |
| 157 c.visibility().SetPublic(); | |
| 158 c.SetToolchain(setup.toolchain()); | |
| 159 Target d(setup.settings(), Label(SourceDir("//foo/"), "d")); | |
| 160 d.set_output_type(Target::SOURCE_SET); | |
| 161 d.visibility().SetPublic(); | |
| 162 d.SetToolchain(setup.toolchain()); | |
| 163 a.private_deps().push_back(LabelTargetPair(&b)); | 147 a.private_deps().push_back(LabelTargetPair(&b)); |
| 164 b.private_deps().push_back(LabelTargetPair(&c)); | 148 b.private_deps().push_back(LabelTargetPair(&c)); |
| 165 c.private_deps().push_back(LabelTargetPair(&d)); | 149 c.private_deps().push_back(LabelTargetPair(&d)); |
| 166 | 150 |
| 167 ASSERT_TRUE(d.OnResolved(&err)); | 151 ASSERT_TRUE(d.OnResolved(&err)); |
| 168 ASSERT_TRUE(c.OnResolved(&err)); | 152 ASSERT_TRUE(c.OnResolved(&err)); |
| 169 ASSERT_TRUE(b.OnResolved(&err)); | 153 ASSERT_TRUE(b.OnResolved(&err)); |
| 170 ASSERT_TRUE(a.OnResolved(&err)); | 154 ASSERT_TRUE(a.OnResolved(&err)); |
| 171 | 155 |
| 172 // C should have D in its inherited libs. | 156 // C should have D in its inherited libs. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 186 ASSERT_EQ(1u, a_inherited.size()); | 170 ASSERT_EQ(1u, a_inherited.size()); |
| 187 EXPECT_EQ(&b, a_inherited[0]); | 171 EXPECT_EQ(&b, a_inherited[0]); |
| 188 } | 172 } |
| 189 | 173 |
| 190 TEST(Target, InheritCompleteStaticLib) { | 174 TEST(Target, InheritCompleteStaticLib) { |
| 191 TestWithScope setup; | 175 TestWithScope setup; |
| 192 Err err; | 176 Err err; |
| 193 | 177 |
| 194 // Create a dependency chain: | 178 // Create a dependency chain: |
| 195 // A (executable) -> B (complete static lib) -> C (source set) | 179 // A (executable) -> B (complete static lib) -> C (source set) |
| 196 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); | 180 TestTarget a(setup, "//foo:a", Target::EXECUTABLE); |
| 197 a.set_output_type(Target::EXECUTABLE); | 181 TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY); |
| 198 a.visibility().SetPublic(); | |
| 199 a.SetToolchain(setup.toolchain()); | |
| 200 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); | |
| 201 b.set_output_type(Target::STATIC_LIBRARY); | |
| 202 b.visibility().SetPublic(); | |
| 203 b.set_complete_static_lib(true); | 182 b.set_complete_static_lib(true); |
| 204 b.SetToolchain(setup.toolchain()); | 183 TestTarget c(setup, "//foo:c", Target::SOURCE_SET); |
| 205 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); | |
| 206 c.set_output_type(Target::SOURCE_SET); | |
| 207 c.visibility().SetPublic(); | |
| 208 c.SetToolchain(setup.toolchain()); | |
| 209 a.public_deps().push_back(LabelTargetPair(&b)); | 184 a.public_deps().push_back(LabelTargetPair(&b)); |
| 210 b.public_deps().push_back(LabelTargetPair(&c)); | 185 b.public_deps().push_back(LabelTargetPair(&c)); |
| 211 | 186 |
| 212 ASSERT_TRUE(c.OnResolved(&err)); | 187 ASSERT_TRUE(c.OnResolved(&err)); |
| 213 ASSERT_TRUE(b.OnResolved(&err)); | 188 ASSERT_TRUE(b.OnResolved(&err)); |
| 214 ASSERT_TRUE(a.OnResolved(&err)); | 189 ASSERT_TRUE(a.OnResolved(&err)); |
| 215 | 190 |
| 216 // B should have C in its inherited libs. | 191 // B should have C in its inherited libs. |
| 217 std::vector<const Target*> b_inherited = b.inherited_libraries().GetOrdered(); | 192 std::vector<const Target*> b_inherited = b.inherited_libraries().GetOrdered(); |
| 218 ASSERT_EQ(1u, b_inherited.size()); | 193 ASSERT_EQ(1u, b_inherited.size()); |
| 219 EXPECT_EQ(&c, b_inherited[0]); | 194 EXPECT_EQ(&c, b_inherited[0]); |
| 220 | 195 |
| 221 // A should have B in its inherited libs, but not any others (the complete | 196 // A should have B in its inherited libs, but not any others (the complete |
| 222 // static library will include the source set). | 197 // static library will include the source set). |
| 223 std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered(); | 198 std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered(); |
| 224 EXPECT_EQ(1u, a_inherited.size()); | 199 EXPECT_EQ(1u, a_inherited.size()); |
| 225 EXPECT_EQ(&b, a_inherited[0]); | 200 EXPECT_EQ(&b, a_inherited[0]); |
| 226 } | 201 } |
| 227 | 202 |
| 228 TEST(Target, InheritCompleteStaticLibNoDirectStaticLibDeps) { | 203 TEST(Target, InheritCompleteStaticLibNoDirectStaticLibDeps) { |
| 229 TestWithScope setup; | 204 TestWithScope setup; |
| 230 Err err; | 205 Err err; |
| 231 | 206 |
| 232 // Create a dependency chain: | 207 // Create a dependency chain: |
| 233 // A (complete static lib) -> B (static lib) | 208 // A (complete static lib) -> B (static lib) |
| 234 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); | 209 TestTarget a(setup, "//foo:a", Target::STATIC_LIBRARY); |
| 235 a.set_output_type(Target::STATIC_LIBRARY); | |
| 236 a.visibility().SetPublic(); | |
| 237 a.set_complete_static_lib(true); | 210 a.set_complete_static_lib(true); |
| 238 a.SetToolchain(setup.toolchain()); | 211 TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY); |
| 239 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); | |
| 240 b.set_output_type(Target::STATIC_LIBRARY); | |
| 241 b.visibility().SetPublic(); | |
| 242 b.SetToolchain(setup.toolchain()); | |
| 243 | 212 |
| 244 a.public_deps().push_back(LabelTargetPair(&b)); | 213 a.public_deps().push_back(LabelTargetPair(&b)); |
| 245 ASSERT_TRUE(b.OnResolved(&err)); | 214 ASSERT_TRUE(b.OnResolved(&err)); |
| 246 ASSERT_FALSE(a.OnResolved(&err)); | 215 ASSERT_FALSE(a.OnResolved(&err)); |
| 247 } | 216 } |
| 248 | 217 |
| 249 TEST(Target, InheritCompleteStaticLibNoIheritedStaticLibDeps) { | 218 TEST(Target, InheritCompleteStaticLibNoIheritedStaticLibDeps) { |
| 250 TestWithScope setup; | 219 TestWithScope setup; |
| 251 Err err; | 220 Err err; |
| 252 | 221 |
| 253 // Create a dependency chain: | 222 // Create a dependency chain: |
| 254 // A (complete static lib) -> B (source set) -> C (static lib) | 223 // A (complete static lib) -> B (source set) -> C (static lib) |
| 255 Target a(setup.settings(), Label(SourceDir("//foo/"), "a")); | 224 TestTarget a(setup, "//foo:a", Target::STATIC_LIBRARY); |
| 256 a.set_output_type(Target::STATIC_LIBRARY); | |
| 257 a.visibility().SetPublic(); | |
| 258 a.set_complete_static_lib(true); | 225 a.set_complete_static_lib(true); |
| 259 a.SetToolchain(setup.toolchain()); | 226 TestTarget b(setup, "//foo:b", Target::SOURCE_SET); |
| 260 Target b(setup.settings(), Label(SourceDir("//foo/"), "b")); | 227 TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY); |
| 261 b.set_output_type(Target::SOURCE_SET); | |
| 262 b.visibility().SetPublic(); | |
| 263 b.SetToolchain(setup.toolchain()); | |
| 264 Target c(setup.settings(), Label(SourceDir("//foo/"), "c")); | |
| 265 c.set_output_type(Target::STATIC_LIBRARY); | |
| 266 c.visibility().SetPublic(); | |
| 267 c.SetToolchain(setup.toolchain()); | |
| 268 | 228 |
| 269 a.public_deps().push_back(LabelTargetPair(&b)); | 229 a.public_deps().push_back(LabelTargetPair(&b)); |
| 270 b.public_deps().push_back(LabelTargetPair(&c)); | 230 b.public_deps().push_back(LabelTargetPair(&c)); |
| 271 | 231 |
| 272 ASSERT_TRUE(c.OnResolved(&err)); | 232 ASSERT_TRUE(c.OnResolved(&err)); |
| 273 ASSERT_TRUE(b.OnResolved(&err)); | 233 ASSERT_TRUE(b.OnResolved(&err)); |
| 274 ASSERT_FALSE(a.OnResolved(&err)); | 234 ASSERT_FALSE(a.OnResolved(&err)); |
| 275 } | 235 } |
| 276 | 236 |
| 277 TEST(Target, GetComputedOutputName) { | 237 TEST(Target, GetComputedOutputName) { |
| 278 TestWithScope setup; | 238 TestWithScope setup; |
| 279 Err err; | 239 Err err; |
| 280 | 240 |
| 281 // Basic target with no prefix (executable type tool in the TestWithScope has | 241 // Basic target with no prefix (executable type tool in the TestWithScope has |
| 282 // no prefix) or output name. | 242 // no prefix) or output name. |
| 283 Target basic(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 243 TestTarget basic(setup, "//foo:bar", Target::EXECUTABLE); |
| 284 basic.set_output_type(Target::EXECUTABLE); | |
| 285 basic.SetToolchain(setup.toolchain()); | |
| 286 ASSERT_TRUE(basic.OnResolved(&err)); | 244 ASSERT_TRUE(basic.OnResolved(&err)); |
| 287 EXPECT_EQ("bar", basic.GetComputedOutputName(false)); | 245 EXPECT_EQ("bar", basic.GetComputedOutputName(false)); |
| 288 EXPECT_EQ("bar", basic.GetComputedOutputName(true)); | 246 EXPECT_EQ("bar", basic.GetComputedOutputName(true)); |
| 289 | 247 |
| 290 // Target with no prefix but an output name. | 248 // Target with no prefix but an output name. |
| 291 Target with_name(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 249 TestTarget with_name(setup, "//foo:bar", Target::EXECUTABLE); |
| 292 with_name.set_output_type(Target::EXECUTABLE); | |
| 293 with_name.set_output_name("myoutput"); | 250 with_name.set_output_name("myoutput"); |
| 294 with_name.SetToolchain(setup.toolchain()); | |
| 295 ASSERT_TRUE(with_name.OnResolved(&err)); | 251 ASSERT_TRUE(with_name.OnResolved(&err)); |
| 296 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false)); | 252 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false)); |
| 297 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true)); | 253 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true)); |
| 298 | 254 |
| 299 // Target with a "lib" prefix (the static library tool in the TestWithScope | 255 // Target with a "lib" prefix (the static library tool in the TestWithScope |
| 300 // should specify a "lib" output prefix). | 256 // should specify a "lib" output prefix). |
| 301 Target with_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 257 TestTarget with_prefix(setup, "//foo:bar", Target::STATIC_LIBRARY); |
| 302 with_prefix.set_output_type(Target::STATIC_LIBRARY); | |
| 303 with_prefix.SetToolchain(setup.toolchain()); | |
| 304 ASSERT_TRUE(with_prefix.OnResolved(&err)); | 258 ASSERT_TRUE(with_prefix.OnResolved(&err)); |
| 305 EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false)); | 259 EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false)); |
| 306 EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true)); | 260 EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true)); |
| 307 | 261 |
| 308 // Target with a "lib" prefix that already has it applied. The prefix should | 262 // Target with a "lib" prefix that already has it applied. The prefix should |
| 309 // not duplicate something already in the target name. | 263 // not duplicate something already in the target name. |
| 310 Target dup_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 264 TestTarget dup_prefix(setup, "//foo:bar", Target::STATIC_LIBRARY); |
| 311 dup_prefix.set_output_type(Target::STATIC_LIBRARY); | |
| 312 dup_prefix.set_output_name("libbar"); | 265 dup_prefix.set_output_name("libbar"); |
| 313 dup_prefix.SetToolchain(setup.toolchain()); | |
| 314 ASSERT_TRUE(dup_prefix.OnResolved(&err)); | 266 ASSERT_TRUE(dup_prefix.OnResolved(&err)); |
| 315 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false)); | 267 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false)); |
| 316 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true)); | 268 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true)); |
| 317 } | 269 } |
| 318 | 270 |
| 319 // Test visibility failure case. | 271 // Test visibility failure case. |
| 320 TEST(Target, VisibilityFails) { | 272 TEST(Target, VisibilityFails) { |
| 321 TestWithScope setup; | 273 TestWithScope setup; |
| 322 Err err; | 274 Err err; |
| 323 | 275 |
| 324 Target b(setup.settings(), Label(SourceDir("//private/"), "b")); | 276 TestTarget b(setup, "//private:b", Target::STATIC_LIBRARY); |
| 325 b.set_output_type(Target::STATIC_LIBRARY); | |
| 326 b.SetToolchain(setup.toolchain()); | |
| 327 b.visibility().SetPrivate(b.label().dir()); | 277 b.visibility().SetPrivate(b.label().dir()); |
| 328 ASSERT_TRUE(b.OnResolved(&err)); | 278 ASSERT_TRUE(b.OnResolved(&err)); |
| 329 | 279 |
| 330 // Make a target depending on "b". The dependency must have an origin to mark | 280 // 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. | 281 // it as user-set so we check visibility. This check should fail. |
| 332 Target a(setup.settings(), Label(SourceDir("//app/"), "a")); | 282 TestTarget a(setup, "//app:a", Target::EXECUTABLE); |
| 333 a.set_output_type(Target::EXECUTABLE); | |
| 334 a.private_deps().push_back(LabelTargetPair(&b)); | 283 a.private_deps().push_back(LabelTargetPair(&b)); |
| 335 IdentifierNode origin; // Dummy origin. | 284 IdentifierNode origin; // Dummy origin. |
| 336 a.private_deps()[0].origin = &origin; | 285 a.private_deps()[0].origin = &origin; |
| 337 a.SetToolchain(setup.toolchain()); | |
| 338 ASSERT_FALSE(a.OnResolved(&err)); | 286 ASSERT_FALSE(a.OnResolved(&err)); |
| 339 } | 287 } |
| 340 | 288 |
| 341 // Test visibility with a single data_dep. | 289 // Test visibility with a single data_dep. |
| 342 TEST(Target, VisibilityDatadeps) { | 290 TEST(Target, VisibilityDatadeps) { |
| 343 TestWithScope setup; | 291 TestWithScope setup; |
| 344 Err err; | 292 Err err; |
| 345 | 293 |
| 346 Target b(setup.settings(), Label(SourceDir("//public/"), "b")); | 294 TestTarget b(setup, "//public:b", Target::STATIC_LIBRARY); |
| 347 b.set_output_type(Target::STATIC_LIBRARY); | |
| 348 b.SetToolchain(setup.toolchain()); | |
| 349 b.visibility().SetPublic(); | |
| 350 ASSERT_TRUE(b.OnResolved(&err)); | 295 ASSERT_TRUE(b.OnResolved(&err)); |
| 351 | 296 |
| 352 // Make a target depending on "b". The dependency must have an origin to mark | 297 // Make a target depending on "b". The dependency must have an origin to mark |
| 353 // it as user-set so we check visibility. This check should fail. | 298 // it as user-set so we check visibility. This check should fail. |
| 354 Target a(setup.settings(), Label(SourceDir("//app/"), "a")); | 299 TestTarget a(setup, "//app:a", Target::EXECUTABLE); |
| 355 a.set_output_type(Target::EXECUTABLE); | |
| 356 a.data_deps().push_back(LabelTargetPair(&b)); | 300 a.data_deps().push_back(LabelTargetPair(&b)); |
| 357 IdentifierNode origin; // Dummy origin. | 301 IdentifierNode origin; // Dummy origin. |
| 358 a.data_deps()[0].origin = &origin; | 302 a.data_deps()[0].origin = &origin; |
| 359 a.SetToolchain(setup.toolchain()); | |
| 360 ASSERT_TRUE(a.OnResolved(&err)) << err.help_text(); | 303 ASSERT_TRUE(a.OnResolved(&err)) << err.help_text(); |
| 361 } | 304 } |
| 362 | 305 |
| 363 // Tests that A -> Group -> B where the group is visible from A but B isn't, | 306 // Tests that A -> Group -> B where the group is visible from A but B isn't, |
| 364 // passes visibility even though the group's deps get expanded into A. | 307 // passes visibility even though the group's deps get expanded into A. |
| 365 TEST(Target, VisibilityGroup) { | 308 TEST(Target, VisibilityGroup) { |
| 366 TestWithScope setup; | 309 TestWithScope setup; |
| 367 Err err; | 310 Err err; |
| 368 | 311 |
| 369 IdentifierNode origin; // Dummy origin. | 312 IdentifierNode origin; // Dummy origin. |
| 370 | 313 |
| 371 // B has private visibility. This lets the group see it since the group is in | 314 // B has private visibility. This lets the group see it since the group is in |
| 372 // the same directory. | 315 // the same directory. |
| 373 Target b(setup.settings(), Label(SourceDir("//private/"), "b")); | 316 TestTarget b(setup, "//private:b", Target::STATIC_LIBRARY); |
| 374 b.set_output_type(Target::STATIC_LIBRARY); | |
| 375 b.SetToolchain(setup.toolchain()); | |
| 376 b.visibility().SetPrivate(b.label().dir()); | 317 b.visibility().SetPrivate(b.label().dir()); |
| 377 ASSERT_TRUE(b.OnResolved(&err)); | 318 ASSERT_TRUE(b.OnResolved(&err)); |
| 378 | 319 |
| 379 // The group has public visibility and depends on b. | 320 // The group has public visibility and depends on b. |
| 380 Target g(setup.settings(), Label(SourceDir("//private/"), "g")); | 321 TestTarget g(setup, "//public:g", Target::GROUP); |
| 381 g.set_output_type(Target::GROUP); | |
| 382 g.SetToolchain(setup.toolchain()); | |
| 383 g.private_deps().push_back(LabelTargetPair(&b)); | 322 g.private_deps().push_back(LabelTargetPair(&b)); |
| 384 g.private_deps()[0].origin = &origin; | 323 g.private_deps()[0].origin = &origin; |
| 385 g.visibility().SetPublic(); | |
| 386 ASSERT_TRUE(b.OnResolved(&err)); | 324 ASSERT_TRUE(b.OnResolved(&err)); |
| 387 | 325 |
| 388 // Make a target depending on "g". This should succeed. | 326 // Make a target depending on "g". This should succeed. |
| 389 Target a(setup.settings(), Label(SourceDir("//app/"), "a")); | 327 TestTarget a(setup, "//app:a", Target::EXECUTABLE); |
| 390 a.set_output_type(Target::EXECUTABLE); | |
| 391 a.private_deps().push_back(LabelTargetPair(&g)); | 328 a.private_deps().push_back(LabelTargetPair(&g)); |
| 392 a.private_deps()[0].origin = &origin; | 329 a.private_deps()[0].origin = &origin; |
| 393 a.SetToolchain(setup.toolchain()); | |
| 394 ASSERT_TRUE(a.OnResolved(&err)); | 330 ASSERT_TRUE(a.OnResolved(&err)); |
| 395 } | 331 } |
| 396 | 332 |
| 397 // Verifies that only testonly targets can depend on other testonly targets. | 333 // Verifies that only testonly targets can depend on other testonly targets. |
| 398 // Many of the above dependency checking cases covered the non-testonly | 334 // Many of the above dependency checking cases covered the non-testonly |
| 399 // case. | 335 // case. |
| 400 TEST(Target, Testonly) { | 336 TEST(Target, Testonly) { |
| 401 TestWithScope setup; | 337 TestWithScope setup; |
| 402 Err err; | 338 Err err; |
| 403 | 339 |
| 404 // "testlib" is a test-only library. | 340 // "testlib" is a test-only library. |
| 405 Target testlib(setup.settings(), Label(SourceDir("//test/"), "testlib")); | 341 TestTarget testlib(setup, "//test:testlib", Target::STATIC_LIBRARY); |
| 406 testlib.set_testonly(true); | 342 testlib.set_testonly(true); |
| 407 testlib.set_output_type(Target::STATIC_LIBRARY); | |
| 408 testlib.visibility().SetPublic(); | |
| 409 testlib.SetToolchain(setup.toolchain()); | |
| 410 ASSERT_TRUE(testlib.OnResolved(&err)); | 343 ASSERT_TRUE(testlib.OnResolved(&err)); |
| 411 | 344 |
| 412 // "test" is a test-only executable depending on testlib, this is OK. | 345 // "test" is a test-only executable depending on testlib, this is OK. |
| 413 Target test(setup.settings(), Label(SourceDir("//test/"), "test")); | 346 TestTarget test(setup, "//test:test", Target::EXECUTABLE); |
| 414 test.set_testonly(true); | 347 test.set_testonly(true); |
| 415 test.set_output_type(Target::EXECUTABLE); | |
| 416 test.private_deps().push_back(LabelTargetPair(&testlib)); | 348 test.private_deps().push_back(LabelTargetPair(&testlib)); |
| 417 test.SetToolchain(setup.toolchain()); | |
| 418 ASSERT_TRUE(test.OnResolved(&err)); | 349 ASSERT_TRUE(test.OnResolved(&err)); |
| 419 | 350 |
| 420 // "product" is a non-test depending on testlib. This should fail. | 351 // "product" is a non-test depending on testlib. This should fail. |
| 421 Target product(setup.settings(), Label(SourceDir("//app/"), "product")); | 352 TestTarget product(setup, "//app:product", Target::EXECUTABLE); |
| 422 product.set_testonly(false); | 353 product.set_testonly(false); |
| 423 product.set_output_type(Target::EXECUTABLE); | |
| 424 product.private_deps().push_back(LabelTargetPair(&testlib)); | 354 product.private_deps().push_back(LabelTargetPair(&testlib)); |
| 425 product.SetToolchain(setup.toolchain()); | |
| 426 ASSERT_FALSE(product.OnResolved(&err)); | 355 ASSERT_FALSE(product.OnResolved(&err)); |
| 427 } | 356 } |
| 428 | 357 |
| 429 TEST(Target, PublicConfigs) { | 358 TEST(Target, PublicConfigs) { |
| 430 TestWithScope setup; | 359 TestWithScope setup; |
| 431 Err err; | 360 Err err; |
| 432 | 361 |
| 433 Label pub_config_label(SourceDir("//a/"), "pubconfig"); | 362 Label pub_config_label(SourceDir("//a/"), "pubconfig"); |
| 434 Config pub_config(setup.settings(), pub_config_label); | 363 Config pub_config(setup.settings(), pub_config_label); |
| 435 | 364 |
| 436 // This is the destination target that has a public config. | 365 // This is the destination target that has a public config. |
| 437 Target dest(setup.settings(), Label(SourceDir("//a/"), "a")); | 366 TestTarget dest(setup, "//a:a", Target::SOURCE_SET); |
| 438 dest.set_output_type(Target::SOURCE_SET); | |
| 439 dest.visibility().SetPublic(); | |
| 440 dest.SetToolchain(setup.toolchain()); | |
| 441 dest.public_configs().push_back(LabelConfigPair(&pub_config)); | 367 dest.public_configs().push_back(LabelConfigPair(&pub_config)); |
| 442 ASSERT_TRUE(dest.OnResolved(&err)); | 368 ASSERT_TRUE(dest.OnResolved(&err)); |
| 443 | 369 |
| 444 // This target has a public dependency on dest. | 370 // This target has a public dependency on dest. |
| 445 Target pub(setup.settings(), Label(SourceDir("//a/"), "pub")); | 371 TestTarget pub(setup, "//a:pub", Target::SOURCE_SET); |
| 446 pub.set_output_type(Target::SOURCE_SET); | |
| 447 pub.visibility().SetPublic(); | |
| 448 pub.SetToolchain(setup.toolchain()); | |
| 449 pub.public_deps().push_back(LabelTargetPair(&dest)); | 372 pub.public_deps().push_back(LabelTargetPair(&dest)); |
| 450 ASSERT_TRUE(pub.OnResolved(&err)); | 373 ASSERT_TRUE(pub.OnResolved(&err)); |
| 451 | 374 |
| 452 // Depending on the target with the public dependency should forward dest's | 375 // Depending on the target with the public dependency should forward dest's |
| 453 // to the current target. | 376 // to the current target. |
| 454 Target dep_on_pub(setup.settings(), Label(SourceDir("//a/"), "dop")); | 377 TestTarget dep_on_pub(setup, "//a:dop", Target::SOURCE_SET); |
| 455 dep_on_pub.set_output_type(Target::SOURCE_SET); | |
| 456 dep_on_pub.visibility().SetPublic(); | |
| 457 dep_on_pub.SetToolchain(setup.toolchain()); | |
| 458 dep_on_pub.private_deps().push_back(LabelTargetPair(&pub)); | 378 dep_on_pub.private_deps().push_back(LabelTargetPair(&pub)); |
| 459 ASSERT_TRUE(dep_on_pub.OnResolved(&err)); | 379 ASSERT_TRUE(dep_on_pub.OnResolved(&err)); |
| 460 ASSERT_EQ(1u, dep_on_pub.configs().size()); | 380 ASSERT_EQ(1u, dep_on_pub.configs().size()); |
| 461 EXPECT_EQ(&pub_config, dep_on_pub.configs()[0].ptr); | 381 EXPECT_EQ(&pub_config, dep_on_pub.configs()[0].ptr); |
| 462 | 382 |
| 463 // This target has a private dependency on dest for forwards configs. | 383 // This target has a private dependency on dest for forwards configs. |
| 464 Target forward(setup.settings(), Label(SourceDir("//a/"), "f")); | 384 TestTarget forward(setup, "//a:f", Target::SOURCE_SET); |
| 465 forward.set_output_type(Target::SOURCE_SET); | |
| 466 forward.visibility().SetPublic(); | |
| 467 forward.SetToolchain(setup.toolchain()); | |
| 468 forward.private_deps().push_back(LabelTargetPair(&dest)); | 385 forward.private_deps().push_back(LabelTargetPair(&dest)); |
| 469 forward.forward_dependent_configs().push_back(LabelTargetPair(&dest)); | 386 forward.forward_dependent_configs().push_back(LabelTargetPair(&dest)); |
| 470 ASSERT_TRUE(forward.OnResolved(&err)); | 387 ASSERT_TRUE(forward.OnResolved(&err)); |
| 471 | 388 |
| 472 // Depending on the forward target should apply the config. | 389 // Depending on the forward target should apply the config. |
| 473 Target dep_on_forward(setup.settings(), Label(SourceDir("//a/"), "dof")); | 390 TestTarget dep_on_forward(setup, "//a:dof", Target::SOURCE_SET); |
| 474 dep_on_forward.set_output_type(Target::SOURCE_SET); | |
| 475 dep_on_forward.visibility().SetPublic(); | |
| 476 dep_on_forward.SetToolchain(setup.toolchain()); | |
| 477 dep_on_forward.private_deps().push_back(LabelTargetPair(&forward)); | 391 dep_on_forward.private_deps().push_back(LabelTargetPair(&forward)); |
| 478 ASSERT_TRUE(dep_on_forward.OnResolved(&err)); | 392 ASSERT_TRUE(dep_on_forward.OnResolved(&err)); |
| 479 ASSERT_EQ(1u, dep_on_forward.configs().size()); | 393 ASSERT_EQ(1u, dep_on_forward.configs().size()); |
| 480 EXPECT_EQ(&pub_config, dep_on_forward.configs()[0].ptr); | 394 EXPECT_EQ(&pub_config, dep_on_forward.configs()[0].ptr); |
| 481 } | 395 } |
| 482 | 396 |
| 483 // Tests that different link/depend outputs work for solink tools. | 397 // Tests that different link/depend outputs work for solink tools. |
| 484 TEST(Target, LinkAndDepOutputs) { | 398 TEST(Target, LinkAndDepOutputs) { |
| 485 TestWithScope setup; | 399 TestWithScope setup; |
| 486 Err err; | 400 Err err; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 517 EXPECT_EQ("./liba.so.TOC", target.dependency_output_file().value()); | 431 EXPECT_EQ("./liba.so.TOC", target.dependency_output_file().value()); |
| 518 } | 432 } |
| 519 | 433 |
| 520 // Shared libraries should be inherited across public shared liobrary | 434 // Shared libraries should be inherited across public shared liobrary |
| 521 // boundaries. | 435 // boundaries. |
| 522 TEST(Target, SharedInheritance) { | 436 TEST(Target, SharedInheritance) { |
| 523 TestWithScope setup; | 437 TestWithScope setup; |
| 524 Err err; | 438 Err err; |
| 525 | 439 |
| 526 // Create two leaf shared libraries. | 440 // Create two leaf shared libraries. |
| 527 Target pub(setup.settings(), Label(SourceDir("//foo/"), "pub")); | 441 TestTarget pub(setup, "//foo:pub", Target::SHARED_LIBRARY); |
| 528 pub.set_output_type(Target::SHARED_LIBRARY); | |
| 529 pub.visibility().SetPublic(); | |
| 530 pub.SetToolchain(setup.toolchain()); | |
| 531 ASSERT_TRUE(pub.OnResolved(&err)); | 442 ASSERT_TRUE(pub.OnResolved(&err)); |
| 532 | 443 |
| 533 Target priv(setup.settings(), Label(SourceDir("//foo/"), "priv")); | 444 TestTarget priv(setup, "//foo:priv", Target::SHARED_LIBRARY); |
| 534 priv.set_output_type(Target::SHARED_LIBRARY); | |
| 535 priv.visibility().SetPublic(); | |
| 536 priv.SetToolchain(setup.toolchain()); | |
| 537 ASSERT_TRUE(priv.OnResolved(&err)); | 445 ASSERT_TRUE(priv.OnResolved(&err)); |
| 538 | 446 |
| 539 // Intermediate shared library with the leaf shared libraries as | 447 // Intermediate shared library with the leaf shared libraries as |
| 540 // dependencies, one public, one private. | 448 // dependencies, one public, one private. |
| 541 Target inter(setup.settings(), Label(SourceDir("//foo/"), "inter")); | 449 TestTarget inter(setup, "//foo:inter", Target::SHARED_LIBRARY); |
| 542 inter.set_output_type(Target::SHARED_LIBRARY); | |
| 543 inter.visibility().SetPublic(); | |
| 544 inter.public_deps().push_back(LabelTargetPair(&pub)); | 450 inter.public_deps().push_back(LabelTargetPair(&pub)); |
| 545 inter.private_deps().push_back(LabelTargetPair(&priv)); | 451 inter.private_deps().push_back(LabelTargetPair(&priv)); |
| 546 inter.SetToolchain(setup.toolchain()); | |
| 547 ASSERT_TRUE(inter.OnResolved(&err)); | 452 ASSERT_TRUE(inter.OnResolved(&err)); |
| 548 | 453 |
| 549 // The intermediate shared library should have both "pub" and "priv" in its | 454 // The intermediate shared library should have both "pub" and "priv" in its |
| 550 // inherited libraries. | 455 // inherited libraries. |
| 551 std::vector<const Target*> inter_inherited = | 456 std::vector<const Target*> inter_inherited = |
| 552 inter.inherited_libraries().GetOrdered(); | 457 inter.inherited_libraries().GetOrdered(); |
| 553 ASSERT_EQ(2u, inter_inherited.size()); | 458 ASSERT_EQ(2u, inter_inherited.size()); |
| 554 EXPECT_EQ(&pub, inter_inherited[0]); | 459 EXPECT_EQ(&pub, inter_inherited[0]); |
| 555 EXPECT_EQ(&priv, inter_inherited[1]); | 460 EXPECT_EQ(&priv, inter_inherited[1]); |
| 556 | 461 |
| 557 // Make a toplevel executable target depending on the intermediate one. | 462 // Make a toplevel executable target depending on the intermediate one. |
| 558 Target exe(setup.settings(), Label(SourceDir("//foo/"), "exe")); | 463 TestTarget exe(setup, "//foo:exe", Target::SHARED_LIBRARY); |
| 559 exe.set_output_type(Target::SHARED_LIBRARY); | |
| 560 exe.visibility().SetPublic(); | |
| 561 exe.private_deps().push_back(LabelTargetPair(&inter)); | 464 exe.private_deps().push_back(LabelTargetPair(&inter)); |
| 562 exe.SetToolchain(setup.toolchain()); | |
| 563 ASSERT_TRUE(exe.OnResolved(&err)); | 465 ASSERT_TRUE(exe.OnResolved(&err)); |
| 564 | 466 |
| 565 // The exe's inherited libraries should be "inter" (because it depended | 467 // The exe's inherited libraries should be "inter" (because it depended |
| 566 // directly on it) and "pub" (because inter depended publicly on it). | 468 // directly on it) and "pub" (because inter depended publicly on it). |
| 567 std::vector<const Target*> exe_inherited = | 469 std::vector<const Target*> exe_inherited = |
| 568 exe.inherited_libraries().GetOrdered(); | 470 exe.inherited_libraries().GetOrdered(); |
| 569 ASSERT_EQ(2u, exe_inherited.size()); | 471 ASSERT_EQ(2u, exe_inherited.size()); |
| 570 EXPECT_EQ(&inter, exe_inherited[0]); | 472 EXPECT_EQ(&inter, exe_inherited[0]); |
| 571 EXPECT_EQ(&pub, exe_inherited[1]); | 473 EXPECT_EQ(&pub, exe_inherited[1]); |
| 572 } | 474 } |
| 475 |
| 476 TEST(Target, GeneratedInputs) { |
| 477 Scheduler scheduler; |
| 478 TestWithScope setup; |
| 479 Err err; |
| 480 |
| 481 SourceFile generated_file("//out/Debug/generated.cc"); |
| 482 |
| 483 // This target has a generated input and no dependency makes it. |
| 484 TestTarget non_existent_generator(setup, "//foo:non_existent_generator", |
| 485 Target::EXECUTABLE); |
| 486 non_existent_generator.sources().push_back(generated_file); |
| 487 EXPECT_TRUE(non_existent_generator.OnResolved(&err)) << err.message(); |
| 488 AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator, |
| 489 generated_file); |
| 490 scheduler.ClearUnknownGeneratedInputsAndWrittenFiles(); |
| 491 |
| 492 // Make a target that generates the file. |
| 493 TestTarget generator(setup, "//foo:generator", Target::ACTION); |
| 494 generator.action_values().outputs() = |
| 495 SubstitutionList::MakeForTest(generated_file.value().c_str()); |
| 496 err = Err(); |
| 497 EXPECT_TRUE(generator.OnResolved(&err)) << err.message(); |
| 498 |
| 499 // A target that depends on the generator that uses the file as a source |
| 500 // should be OK. This uses a private dep (will be used later). |
| 501 TestTarget existent_generator(setup, "//foo:existent_generator", |
| 502 Target::SHARED_LIBRARY); |
| 503 existent_generator.sources().push_back(generated_file); |
| 504 existent_generator.private_deps().push_back(LabelTargetPair(&generator)); |
| 505 EXPECT_TRUE(existent_generator.OnResolved(&err)) << err.message(); |
| 506 EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty()); |
| 507 |
| 508 // A target that depends on the previous one should *not* be allowed to |
| 509 // use the generated file, because existent_generator used private deps. |
| 510 // This is: |
| 511 // indirect_private --> existent_generator --[private]--> generator |
| 512 TestTarget indirect_private(setup, "//foo:indirect_private", |
| 513 Target::EXECUTABLE); |
| 514 indirect_private.sources().push_back(generated_file); |
| 515 indirect_private.public_deps().push_back( |
| 516 LabelTargetPair(&existent_generator)); |
| 517 EXPECT_TRUE(indirect_private.OnResolved(&err)); |
| 518 AssertSchedulerHasOneUnknownFileMatching(&indirect_private, generated_file); |
| 519 scheduler.ClearUnknownGeneratedInputsAndWrittenFiles(); |
| 520 |
| 521 // Now make a chain like the above but with all public deps, it should be OK. |
| 522 TestTarget existent_public(setup, "//foo:existent_public", |
| 523 Target::SHARED_LIBRARY); |
| 524 existent_public.public_deps().push_back(LabelTargetPair(&generator)); |
| 525 EXPECT_TRUE(existent_public.OnResolved(&err)) << err.message(); |
| 526 TestTarget indirect_public(setup, "//foo:indirect_public", |
| 527 Target::EXECUTABLE); |
| 528 indirect_public.sources().push_back(generated_file); |
| 529 indirect_public.public_deps().push_back(LabelTargetPair(&existent_public)); |
| 530 EXPECT_TRUE(indirect_public.OnResolved(&err)) << err.message(); |
| 531 EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty()); |
| 532 } |
| 533 |
| 534 // This is sort of a Scheduler test, but is related to the above test more. |
| 535 TEST(Target, WriteFileGeneratedInputs) { |
| 536 Scheduler scheduler; |
| 537 TestWithScope setup; |
| 538 Err err; |
| 539 |
| 540 SourceFile generated_file("//out/Debug/generated.data"); |
| 541 |
| 542 // This target has a generated input and no dependency makes it. |
| 543 TestTarget non_existent_generator(setup, "//foo:non_existent_generator", |
| 544 Target::EXECUTABLE); |
| 545 non_existent_generator.sources().push_back(generated_file); |
| 546 EXPECT_TRUE(non_existent_generator.OnResolved(&err)); |
| 547 AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator, |
| 548 generated_file); |
| 549 scheduler.ClearUnknownGeneratedInputsAndWrittenFiles(); |
| 550 |
| 551 // This target has a generated file and we've decared we write it. |
| 552 TestTarget existent_generator(setup, "//foo:existent_generator", |
| 553 Target::EXECUTABLE); |
| 554 existent_generator.sources().push_back(generated_file); |
| 555 EXPECT_TRUE(existent_generator.OnResolved(&err)); |
| 556 scheduler.AddWrittenFile(generated_file); |
| 557 |
| 558 // Should be OK. |
| 559 EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty()); |
| 560 } |
| OLD | NEW |