• 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 ()__anon39514de70111::FlagWriter16   void operator()(const std::string& dir, std::ostream& out) const {
17     out << dir << " ";
18   }
19 };
20 
21 struct IncludeWriter {
operator ()__anon39514de70111::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.visibility().SetPublic();
40   dep2_all.own_values().cflags().push_back("--dep2-all");
41   dep2_all.own_values().cflags().push_back("--dep2-all");
42   dep2_all.own_values().include_dirs().push_back(SourceDir("//dep2/all/"));
43   dep2_all.own_values().include_dirs().push_back(SourceDir("//dep2/all/"));
44   ASSERT_TRUE(dep2_all.OnResolved(&err));
45 
46   Config dep2_direct(setup.settings(), Label(SourceDir("//dep2/"), "direct"));
47   dep2_direct.visibility().SetPublic();
48   dep2_direct.own_values().cflags().push_back("--dep2-direct");
49   dep2_direct.own_values().include_dirs().push_back(
50       SourceDir("//dep2/direct/"));
51   ASSERT_TRUE(dep2_direct.OnResolved(&err));
52 
53   Target dep2(setup.settings(), Label(SourceDir("//dep2/"), "dep2"));
54   dep2.set_output_type(Target::SOURCE_SET);
55   dep2.visibility().SetPublic();
56   dep2.SetToolchain(setup.toolchain());
57   dep2.all_dependent_configs().push_back(LabelConfigPair(&dep2_all));
58   dep2.public_configs().push_back(LabelConfigPair(&dep2_direct));
59 
60   // Set up dep1, direct and all dependent configs. Also set up a subconfig
61   // on "dep1_all" to test sub configs.
62   Config dep1_all_sub(setup.settings(), Label(SourceDir("//dep1"), "allch"));
63   dep1_all_sub.visibility().SetPublic();
64   dep1_all_sub.own_values().cflags().push_back("--dep1-all-sub");
65   ASSERT_TRUE(dep1_all_sub.OnResolved(&err));
66 
67   Config dep1_all(setup.settings(), Label(SourceDir("//dep1/"), "all"));
68   dep1_all.visibility().SetPublic();
69   dep1_all.own_values().cflags().push_back("--dep1-all");
70   dep1_all.own_values().include_dirs().push_back(SourceDir("//dep1/all/"));
71   dep1_all.configs().push_back(LabelConfigPair(&dep1_all_sub));
72   ASSERT_TRUE(dep1_all.OnResolved(&err));
73 
74   Config dep1_direct(setup.settings(), Label(SourceDir("//dep1/"), "direct"));
75   dep1_direct.visibility().SetPublic();
76   dep1_direct.own_values().cflags().push_back("--dep1-direct");
77   dep1_direct.own_values().include_dirs().push_back(
78       SourceDir("//dep1/direct/"));
79   ASSERT_TRUE(dep1_direct.OnResolved(&err));
80 
81   Target dep1(setup.settings(), Label(SourceDir("//dep1/"), "dep1"));
82   dep1.set_output_type(Target::SOURCE_SET);
83   dep1.visibility().SetPublic();
84   dep1.SetToolchain(setup.toolchain());
85   dep1.all_dependent_configs().push_back(LabelConfigPair(&dep1_all));
86   dep1.public_configs().push_back(LabelConfigPair(&dep1_direct));
87   dep1.private_deps().push_back(LabelTargetPair(&dep2));
88 
89   // Set up target, direct and all dependent configs.
90   Config target_all(setup.settings(), Label(SourceDir("//target/"), "all"));
91   target_all.visibility().SetPublic();
92   target_all.own_values().cflags().push_back("--target-all");
93   target_all.own_values().include_dirs().push_back(SourceDir("//target/all/"));
94   ASSERT_TRUE(target_all.OnResolved(&err));
95 
96   Config target_direct(setup.settings(),
97                        Label(SourceDir("//target/"), "direct"));
98   target_direct.visibility().SetPublic();
99   target_direct.own_values().cflags().push_back("--target-direct");
100   target_direct.own_values().include_dirs().push_back(
101       SourceDir("//target/direct/"));
102   ASSERT_TRUE(target_direct.OnResolved(&err));
103 
104   // This config is applied directly to target.
105   Config target_config(setup.settings(),
106                        Label(SourceDir("//target/"), "config"));
107   target_config.visibility().SetPublic();
108   target_config.own_values().cflags().push_back("--target-config");
109   target_config.own_values().include_dirs().push_back(
110       SourceDir("//target/config/"));
111   ASSERT_TRUE(target_config.OnResolved(&err));
112 
113   Target target(setup.settings(), Label(SourceDir("//target/"), "target"));
114   target.set_output_type(Target::SOURCE_SET);
115   target.SetToolchain(setup.toolchain());
116   target.all_dependent_configs().push_back(LabelConfigPair(&target_all));
117   target.public_configs().push_back(LabelConfigPair(&target_direct));
118   target.configs().push_back(LabelConfigPair(&target_config));
119   target.private_deps().push_back(LabelTargetPair(&dep1));
120 
121   // Additionally add some values directly on "target".
122   target.config_values().cflags().push_back("--target");
123   target.config_values().include_dirs().push_back(SourceDir("//target/"));
124 
125   // Mark targets resolved. This should push dependent configs.
126   ASSERT_TRUE(dep2.OnResolved(&err));
127   ASSERT_TRUE(dep1.OnResolved(&err));
128   ASSERT_TRUE(target.OnResolved(&err));
129 
130   // Verify cflags by serializing.
131   std::ostringstream flag_out;
132   FlagWriter flag_writer;
133   RecursiveTargetConfigToStream<std::string, FlagWriter>(
134       kRecursiveWriterKeepDuplicates, &target, &ConfigValues::cflags,
135       flag_writer, flag_out);
136   EXPECT_EQ(flag_out.str(),
137             "--target --target-config --target-all --target-direct "
138             "--dep1-all --dep1-all-sub --dep2-all --dep2-all --dep1-direct ");
139 
140   // Verify include dirs by serializing.
141   std::ostringstream include_out;
142   IncludeWriter include_writer;
143   RecursiveTargetConfigToStream<SourceDir, IncludeWriter>(
144       kRecursiveWriterSkipDuplicates, &target, &ConfigValues::include_dirs,
145       include_writer, include_out);
146   EXPECT_EQ(include_out.str(),
147             "//target/ //target/config/ //target/all/ //target/direct/ "
148             "//dep1/all/ //dep2/all/ //dep1/direct/ ");
149 }
150