| Index: tools/gn/target_unittest.cc
|
| diff --git a/tools/gn/target_unittest.cc b/tools/gn/target_unittest.cc
|
| index 9bf0c30df28b3d6dfbe046be3f067c574c7c93cd..25e3aabc4578cf4278958d5ebffedf673132ebfb 100644
|
| --- a/tools/gn/target_unittest.cc
|
| +++ b/tools/gn/target_unittest.cc
|
| @@ -14,37 +14,47 @@
|
| // deps.
|
| TEST(Target, GroupDeps) {
|
| TestWithScope setup;
|
| + Err err;
|
| +
|
| + // Used as the origin for the not-automatically-set deps.
|
| + IdentifierNode origin;
|
|
|
| // Two low-level targets.
|
| Target x(setup.settings(), Label(SourceDir("//component/"), "x"));
|
| x.set_output_type(Target::STATIC_LIBRARY);
|
| x.SetToolchain(setup.toolchain());
|
| - x.OnResolved();
|
| + ASSERT_TRUE(x.OnResolved(&err));
|
| Target y(setup.settings(), Label(SourceDir("//component/"), "y"));
|
| y.set_output_type(Target::STATIC_LIBRARY);
|
| y.SetToolchain(setup.toolchain());
|
| - y.OnResolved();
|
| + ASSERT_TRUE(y.OnResolved(&err));
|
|
|
| // Make a group for both x and y.
|
| Target g(setup.settings(), Label(SourceDir("//group/"), "g"));
|
| g.set_output_type(Target::GROUP);
|
| + g.visibility().SetPublic();
|
| g.deps().push_back(LabelTargetPair(&x));
|
| + g.deps()[0].origin = &origin;
|
| g.deps().push_back(LabelTargetPair(&y));
|
| + g.deps()[1].origin = &origin;
|
|
|
| // Random placeholder target so we can see the group's deps get inserted at
|
| // the right place.
|
| Target b(setup.settings(), Label(SourceDir("//app/"), "b"));
|
| b.set_output_type(Target::STATIC_LIBRARY);
|
| b.SetToolchain(setup.toolchain());
|
| - b.OnResolved();
|
| + b.visibility().SetPublic();
|
| + ASSERT_TRUE(b.OnResolved(&err));
|
|
|
| // Make a target depending on the group and "b". OnResolved will expand.
|
| Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
|
| a.set_output_type(Target::EXECUTABLE);
|
| a.deps().push_back(LabelTargetPair(&g));
|
| + a.deps()[0].origin = &origin;
|
| a.deps().push_back(LabelTargetPair(&b));
|
| + a.deps()[1].origin = &origin;
|
| a.SetToolchain(setup.toolchain());
|
| - a.OnResolved();
|
| + ASSERT_TRUE(a.OnResolved(&err));
|
|
|
| // The group's deps should be inserted after the group itself in the deps
|
| // list, so we should get "g, x, y, b"
|
| @@ -53,12 +63,20 @@ TEST(Target, GroupDeps) {
|
| EXPECT_EQ(&x, a.deps()[1].ptr);
|
| EXPECT_EQ(&y, a.deps()[2].ptr);
|
| EXPECT_EQ(&b, a.deps()[3].ptr);
|
| +
|
| + // The "regular" deps on a should have the origin set. The automatically
|
| + // expanded ones will have a null origin so we know they are generated.
|
| + EXPECT_EQ(&origin, a.deps()[0].origin);
|
| + EXPECT_EQ(NULL, a.deps()[1].origin);
|
| + EXPECT_EQ(NULL, a.deps()[2].origin);
|
| + EXPECT_EQ(&origin, a.deps()[3].origin);
|
| }
|
|
|
| // Tests that lib[_dir]s are inherited across deps boundaries for static
|
| // libraries but not executables.
|
| TEST(Target, LibInheritance) {
|
| TestWithScope setup;
|
| + Err err;
|
|
|
| const std::string lib("foo");
|
| const SourceDir libdir("/foo_dir/");
|
| @@ -69,7 +87,7 @@ TEST(Target, LibInheritance) {
|
| z.config_values().libs().push_back(lib);
|
| z.config_values().lib_dirs().push_back(libdir);
|
| z.SetToolchain(setup.toolchain());
|
| - z.OnResolved();
|
| + ASSERT_TRUE(z.OnResolved(&err));
|
|
|
| // All lib[_dir]s should be set when target is resolved.
|
| ASSERT_EQ(1u, z.all_libs().size());
|
| @@ -87,7 +105,7 @@ TEST(Target, LibInheritance) {
|
| shared.config_values().lib_dirs().push_back(second_libdir);
|
| shared.deps().push_back(LabelTargetPair(&z));
|
| shared.SetToolchain(setup.toolchain());
|
| - shared.OnResolved();
|
| + ASSERT_TRUE(shared.OnResolved(&err));
|
|
|
| ASSERT_EQ(2u, shared.all_libs().size());
|
| EXPECT_EQ(second_lib, shared.all_libs()[0]);
|
| @@ -101,7 +119,7 @@ TEST(Target, LibInheritance) {
|
| exec.set_output_type(Target::EXECUTABLE);
|
| exec.deps().push_back(LabelTargetPair(&shared));
|
| exec.SetToolchain(setup.toolchain());
|
| - exec.OnResolved();
|
| + ASSERT_TRUE(exec.OnResolved(&err));
|
| EXPECT_EQ(0u, exec.all_libs().size());
|
| EXPECT_EQ(0u, exec.all_lib_dirs().size());
|
| }
|
| @@ -110,6 +128,7 @@ TEST(Target, LibInheritance) {
|
| // forward_dependent_configs_from
|
| TEST(Target, DependentConfigs) {
|
| TestWithScope setup;
|
| + Err err;
|
|
|
| // Set up a dependency chain of a -> b -> c
|
| Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
|
| @@ -136,9 +155,9 @@ TEST(Target, DependentConfigs) {
|
| Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct"));
|
| c.direct_dependent_configs().push_back(LabelConfigPair(&direct));
|
|
|
| - c.OnResolved();
|
| - b.OnResolved();
|
| - a.OnResolved();
|
| + ASSERT_TRUE(c.OnResolved(&err));
|
| + ASSERT_TRUE(b.OnResolved(&err));
|
| + ASSERT_TRUE(a.OnResolved(&err));
|
|
|
| // B should have gotten both dependent configs from C.
|
| ASSERT_EQ(2u, b.configs().size());
|
| @@ -163,8 +182,8 @@ TEST(Target, DependentConfigs) {
|
| b_fwd.deps().push_back(LabelTargetPair(&c));
|
| b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c));
|
|
|
| - b_fwd.OnResolved();
|
| - a_fwd.OnResolved();
|
| + ASSERT_TRUE(b_fwd.OnResolved(&err));
|
| + ASSERT_TRUE(a_fwd.OnResolved(&err));
|
|
|
| // A_fwd should now have both configs.
|
| ASSERT_EQ(2u, a_fwd.configs().size());
|
| @@ -178,6 +197,7 @@ TEST(Target, DependentConfigs) {
|
| // group's deps' dependent configs.
|
| TEST(Target, ForwardDependentConfigsFromGroups) {
|
| TestWithScope setup;
|
| + Err err;
|
|
|
| Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
|
| a.set_output_type(Target::EXECUTABLE);
|
| @@ -198,9 +218,9 @@ TEST(Target, ForwardDependentConfigsFromGroups) {
|
| // A forwards the dependent configs from B.
|
| a.forward_dependent_configs().push_back(LabelTargetPair(&b));
|
|
|
| - c.OnResolved();
|
| - b.OnResolved();
|
| - a.OnResolved();
|
| + ASSERT_TRUE(c.OnResolved(&err));
|
| + ASSERT_TRUE(b.OnResolved(&err));
|
| + ASSERT_TRUE(a.OnResolved(&err));
|
|
|
| // The config should now be on A, and in A's direct dependent configs.
|
| ASSERT_EQ(1u, a.configs().size());
|
| @@ -211,6 +231,7 @@ TEST(Target, ForwardDependentConfigsFromGroups) {
|
|
|
| TEST(Target, InheritLibs) {
|
| TestWithScope setup;
|
| + Err err;
|
|
|
| // Create a dependency chain:
|
| // A (executable) -> B (shared lib) -> C (static lib) -> D (source set)
|
| @@ -230,10 +251,10 @@ TEST(Target, InheritLibs) {
|
| b.deps().push_back(LabelTargetPair(&c));
|
| c.deps().push_back(LabelTargetPair(&d));
|
|
|
| - d.OnResolved();
|
| - c.OnResolved();
|
| - b.OnResolved();
|
| - a.OnResolved();
|
| + ASSERT_TRUE(d.OnResolved(&err));
|
| + ASSERT_TRUE(c.OnResolved(&err));
|
| + ASSERT_TRUE(b.OnResolved(&err));
|
| + ASSERT_TRUE(a.OnResolved(&err));
|
|
|
| // C should have D in its inherited libs.
|
| const UniqueVector<const Target*>& c_inherited = c.inherited_libraries();
|
| @@ -255,13 +276,14 @@ TEST(Target, InheritLibs) {
|
|
|
| TEST(Target, GetComputedOutputName) {
|
| TestWithScope setup;
|
| + Err err;
|
|
|
| // 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());
|
| - basic.OnResolved();
|
| + ASSERT_TRUE(basic.OnResolved(&err));
|
| EXPECT_EQ("bar", basic.GetComputedOutputName(false));
|
| EXPECT_EQ("bar", basic.GetComputedOutputName(true));
|
|
|
| @@ -270,7 +292,7 @@ TEST(Target, GetComputedOutputName) {
|
| with_name.set_output_type(Target::EXECUTABLE);
|
| with_name.set_output_name("myoutput");
|
| with_name.SetToolchain(setup.toolchain());
|
| - with_name.OnResolved();
|
| + ASSERT_TRUE(with_name.OnResolved(&err));
|
| EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false));
|
| EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true));
|
|
|
| @@ -279,7 +301,7 @@ TEST(Target, GetComputedOutputName) {
|
| Target with_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar"));
|
| with_prefix.set_output_type(Target::STATIC_LIBRARY);
|
| with_prefix.SetToolchain(setup.toolchain());
|
| - with_prefix.OnResolved();
|
| + ASSERT_TRUE(with_prefix.OnResolved(&err));
|
| EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false));
|
| EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true));
|
|
|
| @@ -289,7 +311,94 @@ TEST(Target, GetComputedOutputName) {
|
| dup_prefix.set_output_type(Target::STATIC_LIBRARY);
|
| dup_prefix.set_output_name("libbar");
|
| dup_prefix.SetToolchain(setup.toolchain());
|
| - dup_prefix.OnResolved();
|
| + ASSERT_TRUE(dup_prefix.OnResolved(&err));
|
| EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false));
|
| EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true));
|
| }
|
| +
|
| +// Test visibility failure case.
|
| +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());
|
| + 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);
|
| + a.deps().push_back(LabelTargetPair(&b));
|
| + IdentifierNode origin; // Dummy origin.
|
| + a.deps()[0].origin = &origin;
|
| + a.SetToolchain(setup.toolchain());
|
| + ASSERT_FALSE(a.OnResolved(&err));
|
| +}
|
| +
|
| +// Tests that A -> Group -> B where the group is visible from A but B isn't,
|
| +// passes visibility even though the group's deps get expanded into A.
|
| +TEST(Target, VisibilityGroup) {
|
| + TestWithScope setup;
|
| + Err err;
|
| +
|
| + IdentifierNode origin; // Dummy origin.
|
| +
|
| + // 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());
|
| + 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());
|
| + g.deps().push_back(LabelTargetPair(&b));
|
| + g.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);
|
| + a.deps().push_back(LabelTargetPair(&g));
|
| + a.deps()[0].origin = &origin;
|
| + a.SetToolchain(setup.toolchain());
|
| + ASSERT_TRUE(a.OnResolved(&err));
|
| +}
|
| +
|
| +// Verifies that only testonly targets can depend on other testonly targets.
|
| +// Many of the above dependency checking cases covered the non-testonly
|
| +// case.
|
| +TEST(Target, Testonly) {
|
| + TestWithScope setup;
|
| + Err err;
|
| +
|
| + // "testlib" is a test-only library.
|
| + Target testlib(setup.settings(), Label(SourceDir("//test/"), "testlib"));
|
| + testlib.set_testonly(true);
|
| + testlib.set_output_type(Target::STATIC_LIBRARY);
|
| + 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"));
|
| + test.set_testonly(true);
|
| + test.set_output_type(Target::EXECUTABLE);
|
| + test.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"));
|
| + product.set_testonly(false);
|
| + product.set_output_type(Target::EXECUTABLE);
|
| + product.deps().push_back(LabelTargetPair(&testlib));
|
| + product.SetToolchain(setup.toolchain());
|
| + ASSERT_FALSE(product.OnResolved(&err));
|
| +}
|
|
|