| Index: tools/gn/target_unittest.cc
|
| diff --git a/tools/gn/target_unittest.cc b/tools/gn/target_unittest.cc
|
| index 020d43226763d0d02b795e574b82d96f87e8c024..48fb84c56fc211ea970e7cfc7101aca6de259ddd 100644
|
| --- a/tools/gn/target_unittest.cc
|
| +++ b/tools/gn/target_unittest.cc
|
| @@ -5,11 +5,30 @@
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "tools/gn/build_settings.h"
|
| #include "tools/gn/config.h"
|
| +#include "tools/gn/scheduler.h"
|
| #include "tools/gn/settings.h"
|
| #include "tools/gn/target.h"
|
| #include "tools/gn/test_with_scope.h"
|
| #include "tools/gn/toolchain.h"
|
|
|
| +namespace {
|
| +
|
| +// Asserts that the current global scheduler has a single unknown generated
|
| +// file with the given name from the given target.
|
| +void AssertSchedulerHasOneUnknownFileMatching(const Target* target,
|
| + const SourceFile& file) {
|
| + auto unknown = g_scheduler->GetUnknownGeneratedInputs();
|
| + ASSERT_EQ(1u, unknown.size()); // Should be one unknown file.
|
| + auto found = unknown.find(file);
|
| + ASSERT_TRUE(found != unknown.end()) << file.value();
|
| + EXPECT_TRUE(target == found->second)
|
| + << "Target doesn't match. Expected\n "
|
| + << target->label().GetUserVisibleName(false)
|
| + << "\nBut got\n " << found->second->label().GetUserVisibleName(false);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| // Tests that lib[_dir]s are inherited across deps boundaries for static
|
| // libraries but not executables.
|
| TEST(Target, LibInheritance) {
|
| @@ -20,12 +39,9 @@ TEST(Target, LibInheritance) {
|
| const SourceDir libdir("/foo_dir/");
|
|
|
| // Leaf target with ldflags set.
|
| - Target z(setup.settings(), Label(SourceDir("//foo/"), "z"));
|
| - z.set_output_type(Target::STATIC_LIBRARY);
|
| + TestTarget z(setup, "//foo:z", Target::STATIC_LIBRARY);
|
| z.config_values().libs().push_back(lib);
|
| z.config_values().lib_dirs().push_back(libdir);
|
| - z.visibility().SetPublic();
|
| - z.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(z.OnResolved(&err));
|
|
|
| // All lib[_dir]s should be set when target is resolved.
|
| @@ -38,13 +54,10 @@ TEST(Target, LibInheritance) {
|
| // and its own. Its own flag should be before the inherited one.
|
| const std::string second_lib("bar");
|
| const SourceDir second_libdir("/bar_dir/");
|
| - Target shared(setup.settings(), Label(SourceDir("//foo/"), "shared"));
|
| - shared.set_output_type(Target::SHARED_LIBRARY);
|
| + TestTarget shared(setup, "//foo:shared", Target::SHARED_LIBRARY);
|
| shared.config_values().libs().push_back(second_lib);
|
| shared.config_values().lib_dirs().push_back(second_libdir);
|
| shared.private_deps().push_back(LabelTargetPair(&z));
|
| - shared.visibility().SetPublic();
|
| - shared.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(shared.OnResolved(&err));
|
|
|
| ASSERT_EQ(2u, shared.all_libs().size());
|
| @@ -55,10 +68,8 @@ TEST(Target, LibInheritance) {
|
| EXPECT_EQ(libdir, shared.all_lib_dirs()[1]);
|
|
|
| // Executable target shouldn't get either by depending on shared.
|
| - Target exec(setup.settings(), Label(SourceDir("//foo/"), "exec"));
|
| - exec.set_output_type(Target::EXECUTABLE);
|
| + TestTarget exec(setup, "//foo:exec", Target::EXECUTABLE);
|
| exec.private_deps().push_back(LabelTargetPair(&shared));
|
| - exec.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(exec.OnResolved(&err));
|
| EXPECT_EQ(0u, exec.all_libs().size());
|
| EXPECT_EQ(0u, exec.all_lib_dirs().size());
|
| @@ -71,18 +82,9 @@ TEST(Target, DependentConfigs) {
|
| Err err;
|
|
|
| // Set up a dependency chain of a -> b -> c
|
| - Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
|
| - a.set_output_type(Target::EXECUTABLE);
|
| - a.visibility().SetPublic();
|
| - a.SetToolchain(setup.toolchain());
|
| - Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
|
| - b.set_output_type(Target::STATIC_LIBRARY);
|
| - b.visibility().SetPublic();
|
| - b.SetToolchain(setup.toolchain());
|
| - Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
|
| - c.set_output_type(Target::STATIC_LIBRARY);
|
| - c.visibility().SetPublic();
|
| - c.SetToolchain(setup.toolchain());
|
| + TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
|
| + TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
|
| + TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
|
| a.private_deps().push_back(LabelTargetPair(&b));
|
| b.private_deps().push_back(LabelTargetPair(&c));
|
|
|
| @@ -115,14 +117,8 @@ TEST(Target, DependentConfigs) {
|
| EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr);
|
|
|
| // Making an an alternate A and B with B forwarding the direct dependents.
|
| - Target a_fwd(setup.settings(), Label(SourceDir("//foo/"), "a_fwd"));
|
| - a_fwd.set_output_type(Target::EXECUTABLE);
|
| - a_fwd.visibility().SetPublic();
|
| - a_fwd.SetToolchain(setup.toolchain());
|
| - Target b_fwd(setup.settings(), Label(SourceDir("//foo/"), "b_fwd"));
|
| - b_fwd.set_output_type(Target::STATIC_LIBRARY);
|
| - b_fwd.SetToolchain(setup.toolchain());
|
| - b_fwd.visibility().SetPublic();
|
| + TestTarget a_fwd(setup, "//foo:a_fwd", Target::EXECUTABLE);
|
| + TestTarget b_fwd(setup, "//foo:b_fwd", Target::STATIC_LIBRARY);
|
| a_fwd.private_deps().push_back(LabelTargetPair(&b_fwd));
|
| b_fwd.private_deps().push_back(LabelTargetPair(&c));
|
| b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c));
|
| @@ -144,22 +140,10 @@ TEST(Target, InheritLibs) {
|
|
|
| // Create a dependency chain:
|
| // A (executable) -> B (shared lib) -> C (static lib) -> D (source set)
|
| - Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
|
| - a.set_output_type(Target::EXECUTABLE);
|
| - a.visibility().SetPublic();
|
| - a.SetToolchain(setup.toolchain());
|
| - Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
|
| - b.set_output_type(Target::SHARED_LIBRARY);
|
| - b.visibility().SetPublic();
|
| - b.SetToolchain(setup.toolchain());
|
| - Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
|
| - c.set_output_type(Target::STATIC_LIBRARY);
|
| - c.visibility().SetPublic();
|
| - c.SetToolchain(setup.toolchain());
|
| - Target d(setup.settings(), Label(SourceDir("//foo/"), "d"));
|
| - d.set_output_type(Target::SOURCE_SET);
|
| - d.visibility().SetPublic();
|
| - d.SetToolchain(setup.toolchain());
|
| + TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
|
| + TestTarget b(setup, "//foo:b", Target::SHARED_LIBRARY);
|
| + TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
|
| + TestTarget d(setup, "//foo:d", Target::SOURCE_SET);
|
| a.private_deps().push_back(LabelTargetPair(&b));
|
| b.private_deps().push_back(LabelTargetPair(&c));
|
| c.private_deps().push_back(LabelTargetPair(&d));
|
| @@ -193,19 +177,10 @@ TEST(Target, InheritCompleteStaticLib) {
|
|
|
| // Create a dependency chain:
|
| // A (executable) -> B (complete static lib) -> C (source set)
|
| - Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
|
| - a.set_output_type(Target::EXECUTABLE);
|
| - a.visibility().SetPublic();
|
| - a.SetToolchain(setup.toolchain());
|
| - Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
|
| - b.set_output_type(Target::STATIC_LIBRARY);
|
| - b.visibility().SetPublic();
|
| + TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
|
| + TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
|
| b.set_complete_static_lib(true);
|
| - b.SetToolchain(setup.toolchain());
|
| - Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
|
| - c.set_output_type(Target::SOURCE_SET);
|
| - c.visibility().SetPublic();
|
| - c.SetToolchain(setup.toolchain());
|
| + TestTarget c(setup, "//foo:c", Target::SOURCE_SET);
|
| a.public_deps().push_back(LabelTargetPair(&b));
|
| b.public_deps().push_back(LabelTargetPair(&c));
|
|
|
| @@ -231,15 +206,9 @@ TEST(Target, InheritCompleteStaticLibNoDirectStaticLibDeps) {
|
|
|
| // Create a dependency chain:
|
| // A (complete static lib) -> B (static lib)
|
| - Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
|
| - a.set_output_type(Target::STATIC_LIBRARY);
|
| - a.visibility().SetPublic();
|
| + TestTarget a(setup, "//foo:a", Target::STATIC_LIBRARY);
|
| a.set_complete_static_lib(true);
|
| - a.SetToolchain(setup.toolchain());
|
| - Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
|
| - b.set_output_type(Target::STATIC_LIBRARY);
|
| - b.visibility().SetPublic();
|
| - b.SetToolchain(setup.toolchain());
|
| + TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
|
|
|
| a.public_deps().push_back(LabelTargetPair(&b));
|
| ASSERT_TRUE(b.OnResolved(&err));
|
| @@ -252,19 +221,10 @@ TEST(Target, InheritCompleteStaticLibNoIheritedStaticLibDeps) {
|
|
|
| // Create a dependency chain:
|
| // A (complete static lib) -> B (source set) -> C (static lib)
|
| - Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
|
| - a.set_output_type(Target::STATIC_LIBRARY);
|
| - a.visibility().SetPublic();
|
| + TestTarget a(setup, "//foo:a", Target::STATIC_LIBRARY);
|
| a.set_complete_static_lib(true);
|
| - a.SetToolchain(setup.toolchain());
|
| - Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
|
| - b.set_output_type(Target::SOURCE_SET);
|
| - b.visibility().SetPublic();
|
| - b.SetToolchain(setup.toolchain());
|
| - Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
|
| - c.set_output_type(Target::STATIC_LIBRARY);
|
| - c.visibility().SetPublic();
|
| - c.SetToolchain(setup.toolchain());
|
| + TestTarget b(setup, "//foo:b", Target::SOURCE_SET);
|
| + TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
|
|
|
| a.public_deps().push_back(LabelTargetPair(&b));
|
| b.public_deps().push_back(LabelTargetPair(&c));
|
| @@ -280,37 +240,29 @@ TEST(Target, GetComputedOutputName) {
|
|
|
| // Basic target with no prefix (executable type tool in the TestWithScope has
|
| // no prefix) or output name.
|
| - Target basic(setup.settings(), Label(SourceDir("//foo/"), "bar"));
|
| - basic.set_output_type(Target::EXECUTABLE);
|
| - basic.SetToolchain(setup.toolchain());
|
| + TestTarget basic(setup, "//foo:bar", Target::EXECUTABLE);
|
| ASSERT_TRUE(basic.OnResolved(&err));
|
| EXPECT_EQ("bar", basic.GetComputedOutputName(false));
|
| EXPECT_EQ("bar", basic.GetComputedOutputName(true));
|
|
|
| // Target with no prefix but an output name.
|
| - Target with_name(setup.settings(), Label(SourceDir("//foo/"), "bar"));
|
| - with_name.set_output_type(Target::EXECUTABLE);
|
| + TestTarget with_name(setup, "//foo:bar", Target::EXECUTABLE);
|
| with_name.set_output_name("myoutput");
|
| - with_name.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(with_name.OnResolved(&err));
|
| EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false));
|
| EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true));
|
|
|
| // Target with a "lib" prefix (the static library tool in the TestWithScope
|
| // should specify a "lib" output prefix).
|
| - Target with_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar"));
|
| - with_prefix.set_output_type(Target::STATIC_LIBRARY);
|
| - with_prefix.SetToolchain(setup.toolchain());
|
| + TestTarget with_prefix(setup, "//foo:bar", Target::STATIC_LIBRARY);
|
| ASSERT_TRUE(with_prefix.OnResolved(&err));
|
| EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false));
|
| EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true));
|
|
|
| // Target with a "lib" prefix that already has it applied. The prefix should
|
| // not duplicate something already in the target name.
|
| - Target dup_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar"));
|
| - dup_prefix.set_output_type(Target::STATIC_LIBRARY);
|
| + TestTarget dup_prefix(setup, "//foo:bar", Target::STATIC_LIBRARY);
|
| dup_prefix.set_output_name("libbar");
|
| - dup_prefix.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(dup_prefix.OnResolved(&err));
|
| EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false));
|
| EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true));
|
| @@ -321,20 +273,16 @@ TEST(Target, VisibilityFails) {
|
| TestWithScope setup;
|
| Err err;
|
|
|
| - Target b(setup.settings(), Label(SourceDir("//private/"), "b"));
|
| - b.set_output_type(Target::STATIC_LIBRARY);
|
| - b.SetToolchain(setup.toolchain());
|
| + TestTarget b(setup, "//private:b", Target::STATIC_LIBRARY);
|
| b.visibility().SetPrivate(b.label().dir());
|
| ASSERT_TRUE(b.OnResolved(&err));
|
|
|
| // Make a target depending on "b". The dependency must have an origin to mark
|
| // it as user-set so we check visibility. This check should fail.
|
| - Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
|
| - a.set_output_type(Target::EXECUTABLE);
|
| + TestTarget a(setup, "//app:a", Target::EXECUTABLE);
|
| a.private_deps().push_back(LabelTargetPair(&b));
|
| IdentifierNode origin; // Dummy origin.
|
| a.private_deps()[0].origin = &origin;
|
| - a.SetToolchain(setup.toolchain());
|
| ASSERT_FALSE(a.OnResolved(&err));
|
| }
|
|
|
| @@ -343,20 +291,15 @@ TEST(Target, VisibilityDatadeps) {
|
| TestWithScope setup;
|
| Err err;
|
|
|
| - Target b(setup.settings(), Label(SourceDir("//public/"), "b"));
|
| - b.set_output_type(Target::STATIC_LIBRARY);
|
| - b.SetToolchain(setup.toolchain());
|
| - b.visibility().SetPublic();
|
| + TestTarget b(setup, "//public:b", Target::STATIC_LIBRARY);
|
| ASSERT_TRUE(b.OnResolved(&err));
|
|
|
| // Make a target depending on "b". The dependency must have an origin to mark
|
| // it as user-set so we check visibility. This check should fail.
|
| - Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
|
| - a.set_output_type(Target::EXECUTABLE);
|
| + TestTarget a(setup, "//app:a", Target::EXECUTABLE);
|
| a.data_deps().push_back(LabelTargetPair(&b));
|
| IdentifierNode origin; // Dummy origin.
|
| a.data_deps()[0].origin = &origin;
|
| - a.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(a.OnResolved(&err)) << err.help_text();
|
| }
|
|
|
| @@ -370,27 +313,20 @@ TEST(Target, VisibilityGroup) {
|
|
|
| // B has private visibility. This lets the group see it since the group is in
|
| // the same directory.
|
| - Target b(setup.settings(), Label(SourceDir("//private/"), "b"));
|
| - b.set_output_type(Target::STATIC_LIBRARY);
|
| - b.SetToolchain(setup.toolchain());
|
| + TestTarget b(setup, "//private:b", Target::STATIC_LIBRARY);
|
| b.visibility().SetPrivate(b.label().dir());
|
| ASSERT_TRUE(b.OnResolved(&err));
|
|
|
| // The group has public visibility and depends on b.
|
| - Target g(setup.settings(), Label(SourceDir("//private/"), "g"));
|
| - g.set_output_type(Target::GROUP);
|
| - g.SetToolchain(setup.toolchain());
|
| + TestTarget g(setup, "//public:g", Target::GROUP);
|
| g.private_deps().push_back(LabelTargetPair(&b));
|
| g.private_deps()[0].origin = &origin;
|
| - g.visibility().SetPublic();
|
| ASSERT_TRUE(b.OnResolved(&err));
|
|
|
| // Make a target depending on "g". This should succeed.
|
| - Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
|
| - a.set_output_type(Target::EXECUTABLE);
|
| + TestTarget a(setup, "//app:a", Target::EXECUTABLE);
|
| a.private_deps().push_back(LabelTargetPair(&g));
|
| a.private_deps()[0].origin = &origin;
|
| - a.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(a.OnResolved(&err));
|
| }
|
|
|
| @@ -402,27 +338,20 @@ TEST(Target, Testonly) {
|
| Err err;
|
|
|
| // "testlib" is a test-only library.
|
| - Target testlib(setup.settings(), Label(SourceDir("//test/"), "testlib"));
|
| + TestTarget testlib(setup, "//test:testlib", Target::STATIC_LIBRARY);
|
| testlib.set_testonly(true);
|
| - testlib.set_output_type(Target::STATIC_LIBRARY);
|
| - testlib.visibility().SetPublic();
|
| - testlib.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(testlib.OnResolved(&err));
|
|
|
| // "test" is a test-only executable depending on testlib, this is OK.
|
| - Target test(setup.settings(), Label(SourceDir("//test/"), "test"));
|
| + TestTarget test(setup, "//test:test", Target::EXECUTABLE);
|
| test.set_testonly(true);
|
| - test.set_output_type(Target::EXECUTABLE);
|
| test.private_deps().push_back(LabelTargetPair(&testlib));
|
| - test.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(test.OnResolved(&err));
|
|
|
| // "product" is a non-test depending on testlib. This should fail.
|
| - Target product(setup.settings(), Label(SourceDir("//app/"), "product"));
|
| + TestTarget product(setup, "//app:product", Target::EXECUTABLE);
|
| product.set_testonly(false);
|
| - product.set_output_type(Target::EXECUTABLE);
|
| product.private_deps().push_back(LabelTargetPair(&testlib));
|
| - product.SetToolchain(setup.toolchain());
|
| ASSERT_FALSE(product.OnResolved(&err));
|
| }
|
|
|
| @@ -434,46 +363,31 @@ TEST(Target, PublicConfigs) {
|
| Config pub_config(setup.settings(), pub_config_label);
|
|
|
| // This is the destination target that has a public config.
|
| - Target dest(setup.settings(), Label(SourceDir("//a/"), "a"));
|
| - dest.set_output_type(Target::SOURCE_SET);
|
| - dest.visibility().SetPublic();
|
| - dest.SetToolchain(setup.toolchain());
|
| + TestTarget dest(setup, "//a:a", Target::SOURCE_SET);
|
| dest.public_configs().push_back(LabelConfigPair(&pub_config));
|
| ASSERT_TRUE(dest.OnResolved(&err));
|
|
|
| // This target has a public dependency on dest.
|
| - Target pub(setup.settings(), Label(SourceDir("//a/"), "pub"));
|
| - pub.set_output_type(Target::SOURCE_SET);
|
| - pub.visibility().SetPublic();
|
| - pub.SetToolchain(setup.toolchain());
|
| + TestTarget pub(setup, "//a:pub", Target::SOURCE_SET);
|
| pub.public_deps().push_back(LabelTargetPair(&dest));
|
| ASSERT_TRUE(pub.OnResolved(&err));
|
|
|
| // Depending on the target with the public dependency should forward dest's
|
| // to the current target.
|
| - Target dep_on_pub(setup.settings(), Label(SourceDir("//a/"), "dop"));
|
| - dep_on_pub.set_output_type(Target::SOURCE_SET);
|
| - dep_on_pub.visibility().SetPublic();
|
| - dep_on_pub.SetToolchain(setup.toolchain());
|
| + TestTarget dep_on_pub(setup, "//a:dop", Target::SOURCE_SET);
|
| dep_on_pub.private_deps().push_back(LabelTargetPair(&pub));
|
| ASSERT_TRUE(dep_on_pub.OnResolved(&err));
|
| ASSERT_EQ(1u, dep_on_pub.configs().size());
|
| EXPECT_EQ(&pub_config, dep_on_pub.configs()[0].ptr);
|
|
|
| // This target has a private dependency on dest for forwards configs.
|
| - Target forward(setup.settings(), Label(SourceDir("//a/"), "f"));
|
| - forward.set_output_type(Target::SOURCE_SET);
|
| - forward.visibility().SetPublic();
|
| - forward.SetToolchain(setup.toolchain());
|
| + TestTarget forward(setup, "//a:f", Target::SOURCE_SET);
|
| forward.private_deps().push_back(LabelTargetPair(&dest));
|
| forward.forward_dependent_configs().push_back(LabelTargetPair(&dest));
|
| ASSERT_TRUE(forward.OnResolved(&err));
|
|
|
| // Depending on the forward target should apply the config.
|
| - Target dep_on_forward(setup.settings(), Label(SourceDir("//a/"), "dof"));
|
| - dep_on_forward.set_output_type(Target::SOURCE_SET);
|
| - dep_on_forward.visibility().SetPublic();
|
| - dep_on_forward.SetToolchain(setup.toolchain());
|
| + TestTarget dep_on_forward(setup, "//a:dof", Target::SOURCE_SET);
|
| dep_on_forward.private_deps().push_back(LabelTargetPair(&forward));
|
| ASSERT_TRUE(dep_on_forward.OnResolved(&err));
|
| ASSERT_EQ(1u, dep_on_forward.configs().size());
|
| @@ -524,26 +438,17 @@ TEST(Target, SharedInheritance) {
|
| Err err;
|
|
|
| // Create two leaf shared libraries.
|
| - Target pub(setup.settings(), Label(SourceDir("//foo/"), "pub"));
|
| - pub.set_output_type(Target::SHARED_LIBRARY);
|
| - pub.visibility().SetPublic();
|
| - pub.SetToolchain(setup.toolchain());
|
| + TestTarget pub(setup, "//foo:pub", Target::SHARED_LIBRARY);
|
| ASSERT_TRUE(pub.OnResolved(&err));
|
|
|
| - Target priv(setup.settings(), Label(SourceDir("//foo/"), "priv"));
|
| - priv.set_output_type(Target::SHARED_LIBRARY);
|
| - priv.visibility().SetPublic();
|
| - priv.SetToolchain(setup.toolchain());
|
| + TestTarget priv(setup, "//foo:priv", Target::SHARED_LIBRARY);
|
| ASSERT_TRUE(priv.OnResolved(&err));
|
|
|
| // Intermediate shared library with the leaf shared libraries as
|
| // dependencies, one public, one private.
|
| - Target inter(setup.settings(), Label(SourceDir("//foo/"), "inter"));
|
| - inter.set_output_type(Target::SHARED_LIBRARY);
|
| - inter.visibility().SetPublic();
|
| + TestTarget inter(setup, "//foo:inter", Target::SHARED_LIBRARY);
|
| inter.public_deps().push_back(LabelTargetPair(&pub));
|
| inter.private_deps().push_back(LabelTargetPair(&priv));
|
| - inter.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(inter.OnResolved(&err));
|
|
|
| // The intermediate shared library should have both "pub" and "priv" in its
|
| @@ -555,11 +460,8 @@ TEST(Target, SharedInheritance) {
|
| EXPECT_EQ(&priv, inter_inherited[1]);
|
|
|
| // Make a toplevel executable target depending on the intermediate one.
|
| - Target exe(setup.settings(), Label(SourceDir("//foo/"), "exe"));
|
| - exe.set_output_type(Target::SHARED_LIBRARY);
|
| - exe.visibility().SetPublic();
|
| + TestTarget exe(setup, "//foo:exe", Target::SHARED_LIBRARY);
|
| exe.private_deps().push_back(LabelTargetPair(&inter));
|
| - exe.SetToolchain(setup.toolchain());
|
| ASSERT_TRUE(exe.OnResolved(&err));
|
|
|
| // The exe's inherited libraries should be "inter" (because it depended
|
| @@ -570,3 +472,89 @@ TEST(Target, SharedInheritance) {
|
| EXPECT_EQ(&inter, exe_inherited[0]);
|
| EXPECT_EQ(&pub, exe_inherited[1]);
|
| }
|
| +
|
| +TEST(Target, GeneratedInputs) {
|
| + Scheduler scheduler;
|
| + TestWithScope setup;
|
| + Err err;
|
| +
|
| + SourceFile generated_file("//out/Debug/generated.cc");
|
| +
|
| + // This target has a generated input and no dependency makes it.
|
| + TestTarget non_existent_generator(setup, "//foo:non_existent_generator",
|
| + Target::EXECUTABLE);
|
| + non_existent_generator.sources().push_back(generated_file);
|
| + EXPECT_TRUE(non_existent_generator.OnResolved(&err)) << err.message();
|
| + AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator,
|
| + generated_file);
|
| + scheduler.ClearUnknownGeneratedInputsAndWrittenFiles();
|
| +
|
| + // Make a target that generates the file.
|
| + TestTarget generator(setup, "//foo:generator", Target::ACTION);
|
| + generator.action_values().outputs() =
|
| + SubstitutionList::MakeForTest(generated_file.value().c_str());
|
| + err = Err();
|
| + EXPECT_TRUE(generator.OnResolved(&err)) << err.message();
|
| +
|
| + // A target that depends on the generator that uses the file as a source
|
| + // should be OK. This uses a private dep (will be used later).
|
| + TestTarget existent_generator(setup, "//foo:existent_generator",
|
| + Target::SHARED_LIBRARY);
|
| + existent_generator.sources().push_back(generated_file);
|
| + existent_generator.private_deps().push_back(LabelTargetPair(&generator));
|
| + EXPECT_TRUE(existent_generator.OnResolved(&err)) << err.message();
|
| + EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty());
|
| +
|
| + // A target that depends on the previous one should *not* be allowed to
|
| + // use the generated file, because existent_generator used private deps.
|
| + // This is:
|
| + // indirect_private --> existent_generator --[private]--> generator
|
| + TestTarget indirect_private(setup, "//foo:indirect_private",
|
| + Target::EXECUTABLE);
|
| + indirect_private.sources().push_back(generated_file);
|
| + indirect_private.public_deps().push_back(
|
| + LabelTargetPair(&existent_generator));
|
| + EXPECT_TRUE(indirect_private.OnResolved(&err));
|
| + AssertSchedulerHasOneUnknownFileMatching(&indirect_private, generated_file);
|
| + scheduler.ClearUnknownGeneratedInputsAndWrittenFiles();
|
| +
|
| + // Now make a chain like the above but with all public deps, it should be OK.
|
| + TestTarget existent_public(setup, "//foo:existent_public",
|
| + Target::SHARED_LIBRARY);
|
| + existent_public.public_deps().push_back(LabelTargetPair(&generator));
|
| + EXPECT_TRUE(existent_public.OnResolved(&err)) << err.message();
|
| + TestTarget indirect_public(setup, "//foo:indirect_public",
|
| + Target::EXECUTABLE);
|
| + indirect_public.sources().push_back(generated_file);
|
| + indirect_public.public_deps().push_back(LabelTargetPair(&existent_public));
|
| + EXPECT_TRUE(indirect_public.OnResolved(&err)) << err.message();
|
| + EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty());
|
| +}
|
| +
|
| +// This is sort of a Scheduler test, but is related to the above test more.
|
| +TEST(Target, WriteFileGeneratedInputs) {
|
| + Scheduler scheduler;
|
| + TestWithScope setup;
|
| + Err err;
|
| +
|
| + SourceFile generated_file("//out/Debug/generated.data");
|
| +
|
| + // This target has a generated input and no dependency makes it.
|
| + TestTarget non_existent_generator(setup, "//foo:non_existent_generator",
|
| + Target::EXECUTABLE);
|
| + non_existent_generator.sources().push_back(generated_file);
|
| + EXPECT_TRUE(non_existent_generator.OnResolved(&err));
|
| + AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator,
|
| + generated_file);
|
| + scheduler.ClearUnknownGeneratedInputsAndWrittenFiles();
|
| +
|
| + // This target has a generated file and we've decared we write it.
|
| + TestTarget existent_generator(setup, "//foo:existent_generator",
|
| + Target::EXECUTABLE);
|
| + existent_generator.sources().push_back(generated_file);
|
| + EXPECT_TRUE(existent_generator.OnResolved(&err));
|
| + scheduler.AddWrittenFile(generated_file);
|
| +
|
| + // Should be OK.
|
| + EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty());
|
| +}
|
|
|