Home | History | Annotate | Download | only in gn
      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