• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 <sstream>
6 
7 #include "gn/config.h"
8 #include "gn/config_values_extractors.h"
9 #include "gn/target.h"
10 #include "gn/test_with_scope.h"
11 #include "util/test/test.h"
12 
13 namespace {
14 
15 struct FlagWriter {
operator ()__anonfd3280de0111::FlagWriter16   void operator()(const std::string& dir, std::ostream& out) const {
17     out << dir << " ";
18   }
19 };
20 
21 struct IncludeWriter {
operator ()__anonfd3280de0111::IncludeWriter22   void operator()(const SourceDir& dir, std::ostream& out) const {
23     out << dir.value() << " ";
24   }
25 };
26 
27 }  // namespace
28 
TEST(ConfigValuesExtractors,IncludeOrdering)29 TEST(ConfigValuesExtractors, IncludeOrdering) {
30   TestWithScope setup;
31   Err err;
32 
33   // Construct a chain of dependencies: target -> dep1 -> dep2
34   // Add representative values: cflags (opaque, always copied) and include_dirs
35   // (uniquified) to each one so we can check what comes out the other end.
36 
37   // Set up dep2, direct and all dependent configs.
38   Config dep2_all(setup.settings(), Label(SourceDir("//dep2/"), "all"));
39   dep2_all.own_values().cflags().push_back("--dep2-all");
40   dep2_all.own_values().include_dirs().push_back(SourceDir("//dep2/all/"));
41   ASSERT_TRUE(dep2_all.OnResolved(&err));
42 
43   Config dep2_direct(setup.settings(), Label(SourceDir("//dep2/"), "direct"));
44   dep2_direct.own_values().cflags().push_back("--dep2-direct");
45   dep2_direct.own_values().include_dirs().push_back(
46       SourceDir("//dep2/direct/"));
47   ASSERT_TRUE(dep2_direct.OnResolved(&err));
48 
49   Target dep2(setup.settings(), Label(SourceDir("//dep2/"), "dep2"));
50   dep2.set_output_type(Target::SOURCE_SET);
51   dep2.visibility().SetPublic();
52   dep2.SetToolchain(setup.toolchain());
53   dep2.all_dependent_configs().push_back(LabelConfigPair(&dep2_all));
54   dep2.public_configs().push_back(LabelConfigPair(&dep2_direct));
55 
56   // Set up dep1, direct and all dependent configs. Also set up a subconfig
57   // on "dep1_all" to test sub configs.
58   Config dep1_all_sub(setup.settings(), Label(SourceDir("//dep1"), "allch"));
59   dep1_all_sub.own_values().cflags().push_back("--dep1-all-sub");
60   ASSERT_TRUE(dep1_all_sub.OnResolved(&err));
61 
62   Config dep1_all(setup.settings(), Label(SourceDir("//dep1/"), "all"));
63   dep1_all.own_values().cflags().push_back("--dep1-all");
64   dep1_all.own_values().include_dirs().push_back(SourceDir("//dep1/all/"));
65   dep1_all.configs().push_back(LabelConfigPair(&dep1_all_sub));
66   ASSERT_TRUE(dep1_all.OnResolved(&err));
67 
68   Config dep1_direct(setup.settings(), Label(SourceDir("//dep1/"), "direct"));
69   dep1_direct.own_values().cflags().push_back("--dep1-direct");
70   dep1_direct.own_values().include_dirs().push_back(
71       SourceDir("//dep1/direct/"));
72   ASSERT_TRUE(dep1_direct.OnResolved(&err));
73 
74   Target dep1(setup.settings(), Label(SourceDir("//dep1/"), "dep1"));
75   dep1.set_output_type(Target::SOURCE_SET);
76   dep1.visibility().SetPublic();
77   dep1.SetToolchain(setup.toolchain());
78   dep1.all_dependent_configs().push_back(LabelConfigPair(&dep1_all));
79   dep1.public_configs().push_back(LabelConfigPair(&dep1_direct));
80   dep1.private_deps().push_back(LabelTargetPair(&dep2));
81 
82   // Set up target, direct and all dependent configs.
83   Config target_all(setup.settings(), Label(SourceDir("//target/"), "all"));
84   target_all.own_values().cflags().push_back("--target-all");
85   target_all.own_values().include_dirs().push_back(SourceDir("//target/all/"));
86   ASSERT_TRUE(target_all.OnResolved(&err));
87 
88   Config target_direct(setup.settings(),
89                        Label(SourceDir("//target/"), "direct"));
90   target_direct.own_values().cflags().push_back("--target-direct");
91   target_direct.own_values().include_dirs().push_back(
92       SourceDir("//target/direct/"));
93   ASSERT_TRUE(target_direct.OnResolved(&err));
94 
95   // This config is applied directly to target.
96   Config target_config(setup.settings(),
97                        Label(SourceDir("//target/"), "config"));
98   target_config.own_values().cflags().push_back("--target-config");
99   target_config.own_values().include_dirs().push_back(
100       SourceDir("//target/config/"));
101   ASSERT_TRUE(target_config.OnResolved(&err));
102 
103   Target target(setup.settings(), Label(SourceDir("//target/"), "target"));
104   target.set_output_type(Target::SOURCE_SET);
105   target.SetToolchain(setup.toolchain());
106   target.all_dependent_configs().push_back(LabelConfigPair(&target_all));
107   target.public_configs().push_back(LabelConfigPair(&target_direct));
108   target.configs().push_back(LabelConfigPair(&target_config));
109   target.private_deps().push_back(LabelTargetPair(&dep1));
110 
111   // Additionally add some values directly on "target".
112   target.config_values().cflags().push_back("--target");
113   target.config_values().include_dirs().push_back(SourceDir("//target/"));
114 
115   // Mark targets resolved. This should push dependent configs.
116   ASSERT_TRUE(dep2.OnResolved(&err));
117   ASSERT_TRUE(dep1.OnResolved(&err));
118   ASSERT_TRUE(target.OnResolved(&err));
119 
120   // Verify cflags by serializing.
121   std::ostringstream flag_out;
122   FlagWriter flag_writer;
123   RecursiveTargetConfigToStream<std::string, FlagWriter>(
124       &target, &ConfigValues::cflags, flag_writer, flag_out);
125   EXPECT_EQ(flag_out.str(),
126             "--target --target-config --target-all --target-direct "
127             "--dep1-all --dep1-all-sub --dep2-all --dep1-direct ");
128 
129   // Verify include dirs by serializing.
130   std::ostringstream include_out;
131   IncludeWriter include_writer;
132   RecursiveTargetConfigToStream<SourceDir, IncludeWriter>(
133       &target, &ConfigValues::include_dirs, include_writer, include_out);
134   EXPECT_EQ(include_out.str(),
135             "//target/ //target/config/ //target/all/ //target/direct/ "
136             "//dep1/all/ //dep2/all/ //dep1/direct/ ");
137 }
138