diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gn/BUILD.gn | 1 | ||||
-rw-r--r-- | tools/gn/config_values_extractors_unittest.cc | 121 | ||||
-rw-r--r-- | tools/gn/gn.gyp | 1 | ||||
-rw-r--r-- | tools/gn/variables.cc | 46 |
4 files changed, 159 insertions, 10 deletions
diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn index 20aea83..9712706 100644 --- a/tools/gn/BUILD.gn +++ b/tools/gn/BUILD.gn @@ -173,6 +173,7 @@ test("gn_unittests") { sources = [ "builder_unittest.cc", "c_include_iterator_unittest.cc", + "config_values_extractors_unittest.cc", "escape_unittest.cc", "filesystem_utils_unittest.cc", "file_template_unittest.cc", diff --git a/tools/gn/config_values_extractors_unittest.cc b/tools/gn/config_values_extractors_unittest.cc new file mode 100644 index 0000000..0076b9e --- /dev/null +++ b/tools/gn/config_values_extractors_unittest.cc @@ -0,0 +1,121 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <sstream> + +#include "testing/gtest/include/gtest/gtest.h" +#include "tools/gn/config.h" +#include "tools/gn/config_values_extractors.h" +#include "tools/gn/target.h" +#include "tools/gn/test_with_scope.h" + +namespace { + +struct FlagWriter { + void operator()(const std::string& dir, std::ostream& out) const { + out << dir << " "; + } +}; + +struct IncludeWriter { + void operator()(const SourceDir& dir, std::ostream& out) const { + out << dir.value() << " "; + } +}; + +} // namespace + +TEST(ConfigValuesExtractors, IncludeOrdering) { + TestWithScope setup; + + // Construct a chain of dependencies: target -> dep1 -> dep2 + // Add representative values: cflags (opaque, always copied) and include_dirs + // (uniquified) to each one so we can check what comes out the other end. + + // Set up dep2, direct and all dependent configs. + Config dep2_all(setup.settings(), Label(SourceDir("//dep2/"), "all")); + dep2_all.config_values().cflags().push_back("--dep2-all"); + dep2_all.config_values().include_dirs().push_back(SourceDir("//dep2/all/")); + + Config dep2_direct(setup.settings(), Label(SourceDir("//dep2/"), "direct")); + dep2_direct.config_values().cflags().push_back("--dep2-direct"); + dep2_direct.config_values().include_dirs().push_back( + SourceDir("//dep2/direct/")); + + Target dep2(setup.settings(), Label(SourceDir("//dep2/"), "dep2")); + dep2.set_output_type(Target::SOURCE_SET); + dep2.all_dependent_configs().push_back(LabelConfigPair(&dep2_all)); + dep2.direct_dependent_configs().push_back(LabelConfigPair(&dep2_direct)); + + // Set up dep1, direct and all dependent configs. + Config dep1_all(setup.settings(), Label(SourceDir("//dep1/"), "all")); + dep1_all.config_values().cflags().push_back("--dep1-all"); + dep1_all.config_values().include_dirs().push_back(SourceDir("//dep1/all/")); + + Config dep1_direct(setup.settings(), Label(SourceDir("//dep1/"), "direct")); + dep1_direct.config_values().cflags().push_back("--dep1-direct"); + dep1_direct.config_values().include_dirs().push_back( + SourceDir("//dep1/direct/")); + + Target dep1(setup.settings(), Label(SourceDir("//dep1/"), "dep1")); + dep1.set_output_type(Target::SOURCE_SET); + dep1.all_dependent_configs().push_back(LabelConfigPair(&dep1_all)); + dep1.direct_dependent_configs().push_back(LabelConfigPair(&dep1_direct)); + dep1.deps().push_back(LabelTargetPair(&dep2)); + + // Set up target, direct and all dependent configs. + Config target_all(setup.settings(), Label(SourceDir("//target/"), "all")); + target_all.config_values().cflags().push_back("--target-all"); + target_all.config_values().include_dirs().push_back( + SourceDir("//target/all/")); + + Config target_direct(setup.settings(), + Label(SourceDir("//target/"), "direct")); + target_direct.config_values().cflags().push_back("--target-direct"); + target_direct.config_values().include_dirs().push_back( + SourceDir("//target/direct/")); + + // This config is applied directly to target. + Config target_config(setup.settings(), + Label(SourceDir("//target/"), "config")); + target_config.config_values().cflags().push_back("--target-config"); + target_config.config_values().include_dirs().push_back( + SourceDir("//target/config/")); + + Target target(setup.settings(), Label(SourceDir("//target/"), "target")); + target.set_output_type(Target::SOURCE_SET); + target.all_dependent_configs().push_back(LabelConfigPair(&target_all)); + target.direct_dependent_configs().push_back(LabelConfigPair(&target_direct)); + target.configs().push_back(LabelConfigPair(&target_config)); + target.deps().push_back(LabelTargetPair(&dep1)); + + + // Additionally add some values directly on "target". + target.config_values().cflags().push_back("--target"); + target.config_values().include_dirs().push_back( + SourceDir("//target/")); + + // Mark targets resolved. This should push dependent configs. + dep2.OnResolved(); + dep1.OnResolved(); + target.OnResolved(); + + // Verify cflags by serializing. + std::ostringstream flag_out; + FlagWriter flag_writer; + RecursiveTargetConfigToStream<std::string, FlagWriter>( + &target, &ConfigValues::cflags, flag_writer, flag_out); + EXPECT_EQ(flag_out.str(), + "--target --target-config --target-all --target-direct " + "--dep1-all --dep2-all --dep1-direct "); + + // Verify include dirs by serializing. + std::ostringstream include_out; + IncludeWriter include_writer; + RecursiveTargetConfigToStream<SourceDir, IncludeWriter>( + &target, &ConfigValues::include_dirs, include_writer, include_out); + EXPECT_EQ(include_out.str(), + "//target/ //target/config/ //target/all/ //target/direct/ " + "//dep1/all/ //dep2/all/ //dep1/direct/ "); +} diff --git a/tools/gn/gn.gyp b/tools/gn/gn.gyp index 0ae37ca..75f72c46 100644 --- a/tools/gn/gn.gyp +++ b/tools/gn/gn.gyp @@ -174,6 +174,7 @@ 'sources': [ 'builder_unittest.cc', 'c_include_iterator_unittest.cc', + 'config_values_extractors_unittest.cc', 'escape_unittest.cc', 'filesystem_utils_unittest.cc', 'file_template_unittest.cc', diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc index 4b49f60..344a9d9 100644 --- a/tools/gn/variables.cc +++ b/tools/gn/variables.cc @@ -240,6 +240,25 @@ const char kTargetOutDir_Help[] = // Target variables ------------------------------------------------------------ +#define COMMON_ORDERING_HELP \ + "\n" \ + "Ordering of flags and values:\n" \ + "\n" \ + " 1. Those set on the current target (not in a config).\n" \ + " 2. Those set on the \"configs\" on the target in order that the\n" \ + " configs appear in the list.\n" \ + " 3. Those set on the \"all_dependent_configs\" on the target in order\n" \ + " that the configs appear in the list.\n" \ + " 4. Those set on the \"direct_dependent_configs\" on the target in\n" \ + " order that those configs appear in the list.\n" \ + " 5. all_dependent_configs pulled from dependencies, in the order of\n" \ + " the \"deps\" list. This is done recursively. If a config appears\n" \ + " more than once, only the first occurance will be used.\n" \ + " 6. direct_dependent_configs pulled from dependencies, in the order\n" \ + " of the \"deps\" list. If a dependency has\n" \ + " \"forward_dependent_configs_from\", they will be applied\n" \ + " recursively.\n" + const char kAllDependentConfigs[] = "all_dependent_configs"; const char kAllDependentConfigs_HelpShort[] = "all_dependent_configs: [label list] Configs to be forced on dependents."; @@ -259,7 +278,8 @@ const char kAllDependentConfigs_Help[] = " capability should generally only be used to add defines and include\n" " directories necessary to compile a target's headers.\n" "\n" - " See also \"direct_dependent_configs\".\n"; + " See also \"direct_dependent_configs\".\n" + COMMON_ORDERING_HELP; const char kArgs[] = "args"; const char kArgs_HelpShort[] = @@ -294,7 +314,8 @@ const char kCommonCflagsHelp[] = " To target one of these variants individually, use \"cflags_c\",\n" " \"cflags_cc\", \"cflags_objc\", and \"cflags_objcc\", respectively.\n" " These variant-specific versions will be appended to the \"cflags\".\n" - COMMON_FLAGS_HELP; + COMMON_FLAGS_HELP + COMMON_ORDERING_HELP; const char* kCflags_Help = kCommonCflagsHelp; const char kCflagsC[] = "cflags_c"; @@ -334,6 +355,7 @@ const char kConfigs_Help[] = " configs applying to a given target type (see \"set_defaults\").\n" " When a target is being defined, it can add to or remove from this\n" " list.\n" + COMMON_ORDERING_HELP "\n" "Example:\n" " static_library(\"foo\") {\n" @@ -392,6 +414,7 @@ const char kDefines_Help[] = "\n" " These strings will be passed to the C/C++ compiler as #defines. The\n" " strings may or may not include an \"=\" to assign a value.\n" + COMMON_ORDERING_HELP "\n" "Example:\n" " defines = [ \"AWESOME_FEATURE\", \"LOG_LEVEL=3\" ]\n"; @@ -464,7 +487,8 @@ const char kDirectDependentConfigs_Help[] = " capability should generally only be used to add defines and include\n" " directories necessary to compile a target's headers.\n" "\n" - " See also \"all_dependent_configs\".\n"; + " See also \"all_dependent_configs\".\n" + COMMON_ORDERING_HELP; const char kForwardDependentConfigsFrom[] = "forward_dependent_configs_from"; const char kForwardDependentConfigsFrom_HelpShort[] = @@ -551,6 +575,7 @@ const char kIncludeDirs_Help[] = "\n" " The directories in this list will be added to the include path for\n" " the files in the affected target.\n" + COMMON_ORDERING_HELP "\n" "Example:\n" " include_dirs = [ \"src/include\", \"//third_party/foo\" ]\n"; @@ -566,6 +591,11 @@ const char kLdflags_Help[] = " These flags are passed on the command-line to the linker and generally\n" " specify various linking options. Most targets will not need these and\n" " will use \"libs\" and \"lib_dirs\" instead.\n" + "\n" + " ldflags are NOT pushed to dependents, so applying ldflags to source\n" + " sets or static libraries will be a no-op. If you want to apply ldflags\n" + " to dependent targets, put them in a config and set it in the\n" + " all_dependent_configs or direct_dependent_configs.\n" COMMON_FLAGS_HELP; #define COMMON_LIB_INHERITANCE_HELP \ @@ -574,13 +604,7 @@ const char kLdflags_Help[] = " First, then are inherited across static library boundaries until a\n" \ " shared library or executable target is reached. Second, they are\n" \ " uniquified so each one is only passed once (the first instance of it\n" \ - " will be the one used).\n" \ - "\n" \ - " The order that libs/lib_dirs apply is:\n" \ - " 1. Ones set on the target itself.\n" \ - " 2. Ones from the configs applying to the target.\n" \ - " 3. Ones from deps of the target, in order (recursively following\n" \ - " these rules).\n" + " will be the one used).\n" const char kLibDirs[] = "lib_dirs"; const char kLibDirs_HelpShort[] = @@ -594,6 +618,7 @@ const char kLibDirs_Help[] = " for the required libraries. If an item is not an absolute path, it\n" " will be treated as being relative to the current build file.\n" COMMON_LIB_INHERITANCE_HELP + COMMON_ORDERING_HELP "\n" "Example:\n" " lib_dirs = [ \"/usr/lib/foo\", \"lib/doom_melon\" ]\n"; @@ -621,6 +646,7 @@ const char kLibs_Help[] = " special-cased: the switch \"-framework\" will be prepended instead of\n" " the lib_prefix, and the \".framework\" suffix will be trimmed.\n" COMMON_LIB_INHERITANCE_HELP + COMMON_ORDERING_HELP "\n" "Examples:\n" " On Windows:\n" |