diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gn/BUILD.gn | 1 | ||||
-rw-r--r-- | tools/gn/functions.cc | 1 | ||||
-rw-r--r-- | tools/gn/functions.h | 8 | ||||
-rw-r--r-- | tools/gn/functions_target.cc | 75 | ||||
-rw-r--r-- | tools/gn/gn.gyp | 1 | ||||
-rw-r--r-- | tools/gn/ninja_binary_target_writer.cc | 171 | ||||
-rw-r--r-- | tools/gn/ninja_binary_target_writer.h | 28 | ||||
-rw-r--r-- | tools/gn/ninja_binary_target_writer_unittest.cc | 89 | ||||
-rw-r--r-- | tools/gn/ninja_helper.cc | 1 | ||||
-rw-r--r-- | tools/gn/ninja_script_target_writer_unittest.cc | 8 | ||||
-rw-r--r-- | tools/gn/ninja_target_writer.cc | 3 | ||||
-rw-r--r-- | tools/gn/output_file.h | 5 | ||||
-rw-r--r-- | tools/gn/secondary/build/config/BUILDCONFIG.gn | 6 | ||||
-rw-r--r-- | tools/gn/secondary/build/toolchain/nacl/BUILD.gn | 12 | ||||
-rw-r--r-- | tools/gn/secondary/chrome/BUILD.gn | 8 | ||||
-rw-r--r-- | tools/gn/target.cc | 3 | ||||
-rw-r--r-- | tools/gn/target.h | 7 | ||||
-rw-r--r-- | tools/gn/target_generator.cc | 4 |
18 files changed, 365 insertions, 66 deletions
diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn index e3d5301..9ff4081 100644 --- a/tools/gn/BUILD.gn +++ b/tools/gn/BUILD.gn @@ -161,6 +161,7 @@ test("gn_unittests") { "function_rebase_path_unittest.cc", "input_conversion_unittest.cc", "label_unittest.cc", + "ninja_binary_target_writer_unittest.cc", "ninja_copy_target_writer_unittest.cc", "ninja_helper_unittest.cc", "ninja_script_target_writer_unittest.cc", diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc index bac4b8e..acc8fe9 100644 --- a/tools/gn/functions.cc +++ b/tools/gn/functions.cc @@ -567,6 +567,7 @@ struct FunctionInfoInitializer { INSERT_FUNCTION(SetDefaultToolchain) INSERT_FUNCTION(SetSourcesAssignmentFilter) INSERT_FUNCTION(SharedLibrary) + INSERT_FUNCTION(SourceSet) INSERT_FUNCTION(StaticLibrary) INSERT_FUNCTION(Template) INSERT_FUNCTION(Test) diff --git a/tools/gn/functions.h b/tools/gn/functions.h index 9c419cc..4a7833a 100644 --- a/tools/gn/functions.h +++ b/tools/gn/functions.h @@ -194,6 +194,14 @@ Value RunSharedLibrary(Scope* scope, BlockNode* block, Err* err); +extern const char kSourceSet[]; +extern const char kSourceSet_Help[]; +Value RunSourceSet(Scope* scope, + const FunctionCallNode* function, + const std::vector<Value>& args, + BlockNode* block, + Err* err); + extern const char kStaticLibrary[]; extern const char kStaticLibrary_Help[]; Value RunStaticLibrary(Scope* scope, diff --git a/tools/gn/functions_target.cc b/tools/gn/functions_target.cc index 94a04e4..fc968e5 100644 --- a/tools/gn/functions_target.cc +++ b/tools/gn/functions_target.cc @@ -58,18 +58,19 @@ const char kComponent[] = "component"; const char kComponent_Help[] = "component: Declare a component target.\n" "\n" - " A component is either a shared library or a static library depending\n" - " on the component mode. This allows a project to separate out a build\n" - " into shared libraries for faster devlopment (link time is reduced)\n" - " but to switch to a static build for releases (for better performance).\n" + " A component is a shared library, static library, or source set\n" + " depending on the component mode. This allows a project to separate\n" + " out a build into shared libraries for faster devlopment (link time is\n" + " reduced) but to switch to a static build for releases (for better\n" + " performance).\n" "\n" " To use this function you must set the value of the \"component_mode\n" - " variable to the string \"shared_library\" or \"static_library\". It is\n" - " an error to call \"component\" without defining the mode (typically\n" - " this is done in the master build configuration file).\n" - "\n" - " See \"gn help shared_library\" and \"gn help static_library\" for\n" - " more details.\n"; + " variable to one of the following strings:\n" + " - \"shared_library\"\n" + " - \"static_library\"\n" + " - \"source_set\"\n" + " It is an error to call \"component\" without defining the mode\n" + " (typically this is done in the master build configuration file).\n"; Value RunComponent(Scope* scope, const FunctionCallNode* function, @@ -90,7 +91,8 @@ Value RunComponent(Scope* scope, } if (component_mode_value->type() != Value::STRING || (component_mode_value->string_value() != functions::kSharedLibrary && - component_mode_value->string_value() != functions::kStaticLibrary)) { + component_mode_value->string_value() != functions::kStaticLibrary && + component_mode_value->string_value() != functions::kSourceSet)) { *err = Err(function->function(), "Invalid component mode set.", helptext); return Value(); } @@ -339,12 +341,63 @@ Value RunSharedLibrary(Scope* scope, block, err); } +// source_set ------------------------------------------------------------------ + +extern const char kSourceSet[] = "source_set"; +extern const char kSourceSet_Help[] = + "source_set: Declare a source set target.\n" + "\n" + " A source set is a collection of sources that get compiled, but are not\n" + " linked to produce any kind of library. Instead, the resulting object\n" + " files are implicitly added to the linker line of all targets that\n" + " depend on the source set.\n" + "\n" + " In most cases, a source set will behave like a static library, except\n" + " no actual library file will be produced. This will make the build go\n" + " a little faster by skipping creation of a large static library, while\n" + " maintaining the organizational benefits of focused build targets.\n" + "\n" + " The main difference between a source set and a static library is\n" + " around handling of exported symbols. Most linkers assume declaring\n" + " a function exported means exported from the static library. The linker\n" + " can then do dead code elimination to delete code not reachable from\n" + " exported functions.\n" + "\n" + " A source set will not do this code elimination since there is no link\n" + " step. This allows you to link many sources sets into a shared library\n" + " and have the \"exported symbol\" notation indicate \"export from the\n" + " final shared library and not from the intermediate targets.\" There is\n" + " no way to express this concept when linking multiple static libraries\n" + " into a shared library.\n" + "\n" + "Variables\n" + "\n" + CONFIG_VALUES_VARS_HELP + DEPS_VARS + DEPENDENT_CONFIG_VARS + GENERAL_TARGET_VARS; + +Value RunSourceSet(Scope* scope, + const FunctionCallNode* function, + const std::vector<Value>& args, + BlockNode* block, + Err* err) { + return ExecuteGenericTarget(functions::kSourceSet, scope, function, args, + block, err); +} + // static_library -------------------------------------------------------------- const char kStaticLibrary[] = "static_library"; const char kStaticLibrary_Help[] = "static_library: Declare a static library target.\n" "\n" + " Make a \".a\" / \".lib\" file.\n" + "\n" + " If you only need the static library for intermediate results in the\n" + " build, you should consider a source_set instead since it will skip\n" + " the (potentially slow) step of creating the intermediate library file.\n" + "\n" "Variables\n" "\n" CONFIG_VALUES_VARS_HELP diff --git a/tools/gn/gn.gyp b/tools/gn/gn.gyp index fb5a53e..c19d2ef 100644 --- a/tools/gn/gn.gyp +++ b/tools/gn/gn.gyp @@ -171,6 +171,7 @@ 'function_rebase_path_unittest.cc', 'input_conversion_unittest.cc', 'label_unittest.cc', + 'ninja_binary_target_writer_unittest.cc', 'ninja_helper_unittest.cc', 'ninja_copy_target_writer_unittest.cc', 'ninja_script_target_writer_unittest.cc', diff --git a/tools/gn/ninja_binary_target_writer.cc b/tools/gn/ninja_binary_target_writer.cc index 60d3a6a..9241021 100644 --- a/tools/gn/ninja_binary_target_writer.cc +++ b/tools/gn/ninja_binary_target_writer.cc @@ -79,7 +79,6 @@ Toolchain::ToolType GetToolTypeForTarget(const Target* target) { case Target::EXECUTABLE: return Toolchain::TYPE_LINK; default: - NOTREACHED(); return Toolchain::TYPE_NONE; } } @@ -103,7 +102,10 @@ void NinjaBinaryTargetWriter::Run() { std::vector<OutputFile> obj_files; WriteSources(&obj_files); - WriteLinkerStuff(obj_files); + if (target_->output_type() == Target::SOURCE_SET) + WriteSourceSetStamp(obj_files); + else + WriteLinkerStuff(obj_files); } void NinjaBinaryTargetWriter::WriteCompilerVars() { @@ -309,40 +311,26 @@ void NinjaBinaryTargetWriter::WriteLinkCommand( << helper_.GetRulePrefix(GetToolchain()) << Toolchain::ToolTypeToName(tool_type_); + std::set<OutputFile> extra_object_files; + std::vector<const Target*> linkable_deps; + std::vector<const Target*> non_linkable_deps; + GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps); + // Object files. for (size_t i = 0; i < object_files.size(); i++) { out_ << " "; path_output_.WriteFile(out_, object_files[i]); } - - // Library inputs (deps and inherited static libraries). - // - // Static libraries since they're just a collection of the object files so - // don't need libraries linked with them, but we still need to go through - // the list and find non-linkable data deps in the "deps" section. We'll - // collect all non-linkable deps and put it in the implicit deps below. - std::vector<const Target*> extra_data_deps; - const std::vector<const Target*>& deps = target_->deps(); - const std::set<const Target*>& inherited = target_->inherited_libraries(); - for (size_t i = 0; i < deps.size(); i++) { - if (inherited.find(deps[i]) != inherited.end()) - continue; - if (target_->output_type() != Target::STATIC_LIBRARY && - deps[i]->IsLinkable()) { - out_ << " "; - path_output_.WriteFile(out_, helper_.GetTargetOutputFile(deps[i])); - } else { - extra_data_deps.push_back(deps[i]); - } + for (std::set<OutputFile>::iterator i = extra_object_files.begin(); + i != extra_object_files.end(); ++i) { + out_ << " "; + path_output_.WriteFile(out_, *i); } - for (std::set<const Target*>::const_iterator i = inherited.begin(); - i != inherited.end(); ++i) { - if (target_->output_type() == Target::STATIC_LIBRARY) { - extra_data_deps.push_back(*i); - } else { - out_ << " "; - path_output_.WriteFile(out_, helper_.GetTargetOutputFile(*i)); - } + + // Libs. + for (size_t i = 0; i < linkable_deps.size(); i++) { + out_ << " "; + path_output_.WriteFile(out_, helper_.GetTargetOutputFile(linkable_deps[i])); } // External link deps from GYP. This is indexed by a label with no toolchain. @@ -357,22 +345,123 @@ void NinjaBinaryTargetWriter::WriteLinkCommand( } // Append data dependencies as implicit dependencies. + WriteImplicitDependencies(non_linkable_deps); + + out_ << std::endl; +} + +void NinjaBinaryTargetWriter::WriteSourceSetStamp( + const std::vector<OutputFile>& object_files) { + // The stamp rule for source sets is generally not used, since targets that + // depend on this will reference the object files directly. However, writing + // this rule allows the user to type the name of the target and get a build + // which can be convenient for development. + out_ << "build "; + path_output_.WriteFile(out_, helper_.GetTargetOutputFile(target_)); + out_ << ": " + << helper_.GetRulePrefix(target_->settings()->toolchain()) + << "stamp"; + + std::set<OutputFile> extra_object_files; + std::vector<const Target*> linkable_deps; + std::vector<const Target*> non_linkable_deps; + GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps); + + // The classifier should never put extra object files in a source set: + // any source sets that we depend on should appear in our non-linkable + // deps instead. + DCHECK(extra_object_files.empty()); + + for (size_t i = 0; i < object_files.size(); i++) { + out_ << " "; + path_output_.WriteFile(out_, object_files[i]); + } + + // Append data dependencies as implicit dependencies. + WriteImplicitDependencies(non_linkable_deps); + + out_ << std::endl; +} + +void NinjaBinaryTargetWriter::GetDeps( + std::set<OutputFile>* extra_object_files, + std::vector<const Target*>* linkable_deps, + std::vector<const Target*>* non_linkable_deps) const { + const std::vector<const Target*>& deps = target_->deps(); + const std::set<const Target*>& inherited = target_->inherited_libraries(); + + // Normal deps. + for (size_t i = 0; i < deps.size(); i++) { + if (inherited.find(deps[i]) != inherited.end()) + continue; // Don't add dupes. + ClassifyDependency(deps[i], extra_object_files, + linkable_deps, non_linkable_deps); + } + + // Inherited libraries. + for (std::set<const Target*>::const_iterator i = inherited.begin(); + i != inherited.end(); ++i) { + ClassifyDependency(*i, extra_object_files, + linkable_deps, non_linkable_deps); + } + + // Data deps. const std::vector<const Target*>& datadeps = target_->datadeps(); + for (size_t i = 0; i < datadeps.size(); i++) + non_linkable_deps->push_back(datadeps[i]); +} + +void NinjaBinaryTargetWriter::ClassifyDependency( + const Target* dep, + std::set<OutputFile>* extra_object_files, + std::vector<const Target*>* linkable_deps, + std::vector<const Target*>* non_linkable_deps) const { + // Only these types of outputs have libraries linked into them. Child deps of + // static libraries get pushed up the dependency tree until one of these is + // reached, and source sets don't link at all. + bool can_link_libs = + (target_->output_type() == Target::EXECUTABLE || + target_->output_type() == Target::SHARED_LIBRARY); + + if (dep->output_type() == Target::SOURCE_SET) { + if (target_->output_type() == Target::SOURCE_SET) { + // When a source set depends on another source set, add it as a data + // dependency so if the user says "ninja second_source_set" it will + // also compile the first (what you would expect) even though we'll + // never do anything with the first one's files. + non_linkable_deps->push_back(dep); + } else { + // Linking in a source set, copy its object files. + for (size_t i = 0; i < dep->sources().size(); i++) { + SourceFileType input_file_type = GetSourceFileType( + dep->sources()[i], dep->settings()->target_os()); + if (input_file_type != SOURCE_UNKNOWN && + input_file_type != SOURCE_H) { + // Note we need to specify the target as the source_set target + // itself, since this is used to prefix the object file name. + extra_object_files->insert(helper_.GetOutputFileForSource( + dep, dep->sources()[i], input_file_type)); + } + } + } + } else if (can_link_libs && dep->IsLinkable()) { + linkable_deps->push_back(dep); + } else { + non_linkable_deps->push_back(dep); + } +} + +void NinjaBinaryTargetWriter::WriteImplicitDependencies( + const std::vector<const Target*>& non_linkable_deps) { const std::vector<SourceFile>& data = target_->data(); - if (!extra_data_deps.empty() || !datadeps.empty() || !data.empty()) { + if (!non_linkable_deps.empty() || !data.empty()) { out_ << " ||"; - // Non-linkable deps in the deps section above. - for (size_t i = 0; i < extra_data_deps.size(); i++) { + // Non-linkable targets. + for (size_t i = 0; i < non_linkable_deps.size(); i++) { out_ << " "; path_output_.WriteFile(out_, - helper_.GetTargetOutputFile(extra_data_deps[i])); - } - - // Data deps. - for (size_t i = 0; i < datadeps.size(); i++) { - out_ << " "; - path_output_.WriteFile(out_, helper_.GetTargetOutputFile(datadeps[i])); + helper_.GetTargetOutputFile(non_linkable_deps[i])); } // Data files. @@ -382,6 +471,4 @@ void NinjaBinaryTargetWriter::WriteLinkCommand( path_output_.WriteFile(out_, data[i]); } } - - out_ << std::endl; } diff --git a/tools/gn/ninja_binary_target_writer.h b/tools/gn/ninja_binary_target_writer.h index 047ed2a..8c57ffb 100644 --- a/tools/gn/ninja_binary_target_writer.h +++ b/tools/gn/ninja_binary_target_writer.h @@ -19,6 +19,8 @@ class NinjaBinaryTargetWriter : public NinjaTargetWriter { virtual void Run() OVERRIDE; private: + typedef std::set<OutputFile> OutputFileSet; + void WriteCompilerVars(); void WriteSources(std::vector<OutputFile>* object_files); void WriteLinkerStuff(const std::vector<OutputFile>& object_files); @@ -29,6 +31,32 @@ class NinjaBinaryTargetWriter : public NinjaTargetWriter { const OutputFile& internal_output_file, const std::vector<OutputFile>& object_files); + // Writes the stamp line for a source set. These are not linked. + void WriteSourceSetStamp(const std::vector<OutputFile>& object_files); + + // Gets all target dependencies and classifies them, as well as accumulates + // object files from source sets we need to link. + void GetDeps(std::set<OutputFile>* extra_object_files, + std::vector<const Target*>* linkable_deps, + std::vector<const Target*>* non_linkable_deps) const; + + // Classifies the dependency as linkable or nonlinkable with the current + // target, adding it to the appropriate vector. If the dependency is a source + // set we should link in, the source set's object files will be appended to + // |extra_object_files|. + void ClassifyDependency(const Target* dep, + std::set<OutputFile>* extra_object_files, + std::vector<const Target*>* linkable_deps, + std::vector<const Target*>* non_linkable_deps) const; + + // Writes the implicit dependencies for the link or stamp line. This is + // the "||" and everything following it on the ninja line. + // + // The implicit dependencies are the non-linkable deps passed in as an + // argument, plus the data file depdencies in the target. + void WriteImplicitDependencies( + const std::vector<const Target*>& non_linkable_deps); + Toolchain::ToolType tool_type_; DISALLOW_COPY_AND_ASSIGN(NinjaBinaryTargetWriter); diff --git a/tools/gn/ninja_binary_target_writer_unittest.cc b/tools/gn/ninja_binary_target_writer_unittest.cc new file mode 100644 index 0000000..f57bb19 --- /dev/null +++ b/tools/gn/ninja_binary_target_writer_unittest.cc @@ -0,0 +1,89 @@ +// Copyright (c) 2013 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/ninja_binary_target_writer.h"
+#include "tools/gn/test_with_scope.h"
+
+TEST(NinjaBinaryTargetWriter, SourceSet) {
+ TestWithScope setup;
+ setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
+ setup.settings()->set_target_os(Settings::WIN);
+
+ Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+ target.set_output_type(Target::SOURCE_SET);
+ target.sources().push_back(SourceFile("//foo/input1.cc"));
+ target.sources().push_back(SourceFile("//foo/input2.cc"));
+ target.OnResolved();
+
+ // Source set itself.
+ {
+ std::ostringstream out;
+ NinjaBinaryTargetWriter writer(&target, out);
+ writer.Run();
+
+ // TODO(brettw) I think we'll need to worry about backslashes here
+ // depending if we're on actual Windows or Linux pretending to be Windows.
+ const char expected_win[] =
+ "arch = environment.x86\n"
+ "defines =\n"
+ "includes =\n"
+ "cflags =\n"
+ "cflags_c =\n"
+ "cflags_cc =\n"
+ "cflags_objc =\n"
+ "cflags_objcc =\n"
+ "\n"
+ "build obj/foo/bar.input1.obj: tc_cxx ../../foo/input1.cc\n"
+ "build obj/foo/bar.input2.obj: tc_cxx ../../foo/input2.cc\n"
+ "\n"
+ "build obj/foo/bar.stamp: tc_stamp obj/foo/bar.input1.obj obj/foo/bar.input2.obj\n";
+ std::string out_str = out.str();
+#if defined(OS_WIN)
+ std::replace(out_str.begin(), out_str.end(), '\\', '/');
+#endif
+ EXPECT_EQ(expected_win, out_str);
+ }
+
+ // A shared library that depends on the source set.
+ Target shlib_target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
+ shlib_target.set_output_type(Target::SHARED_LIBRARY);
+ shlib_target.deps().push_back(&target);
+ shlib_target.OnResolved();
+
+ {
+ std::ostringstream out;
+ NinjaBinaryTargetWriter writer(&shlib_target, out);
+ writer.Run();
+
+ // TODO(brettw) I think we'll need to worry about backslashes here
+ // depending if we're on actual Windows or Linux pretending to be Windows.
+ const char expected_win[] =
+ "arch = environment.x86\n"
+ "defines =\n"
+ "includes =\n"
+ "cflags =\n"
+ "cflags_c =\n"
+ "cflags_cc =\n"
+ "cflags_objc =\n"
+ "cflags_objcc =\n"
+ "\n"
+ "\n"
+ "manifests = obj/foo/shlib.intermediate.manifest\n"
+ "ldflags = /MANIFEST /ManifestFile:obj/foo/shlib.intermediate.manifest\n"
+ "libs =\n"
+ "build shlib.dll shlib.dll.lib: tc_solink obj/foo/bar.input1.obj obj/foo/bar.input2.obj\n"
+ " soname = shlib.dll\n"
+ " lib = shlib.dll\n"
+ " dll = shlib.dll\n"
+ " implibflag = /IMPLIB:shlib.dll.lib\n\n";
+ std::string out_str = out.str();
+#if defined(OS_WIN)
+ std::replace(out_str.begin(), out_str.end(), '\\', '/');
+#endif
+ EXPECT_EQ(expected_win, out_str);
+ }
+}
diff --git a/tools/gn/ninja_helper.cc b/tools/gn/ninja_helper.cc index 9af5c38..d90b698 100644 --- a/tools/gn/ninja_helper.cc +++ b/tools/gn/ninja_helper.cc @@ -132,6 +132,7 @@ OutputFile NinjaHelper::GetTargetOutputFile(const Target* target) const { const char* extension; if (target->output_type() == Target::GROUP || + target->output_type() == Target::SOURCE_SET || target->output_type() == Target::COPY_FILES || target->output_type() == Target::CUSTOM) { extension = "stamp"; diff --git a/tools/gn/ninja_script_target_writer_unittest.cc b/tools/gn/ninja_script_target_writer_unittest.cc index 9fa018e..2057f07 100644 --- a/tools/gn/ninja_script_target_writer_unittest.cc +++ b/tools/gn/ninja_script_target_writer_unittest.cc @@ -113,6 +113,10 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { // Windows. { + // Note: we use forward slashes here so that the output will be the same on + // Linux and Windows. + setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( + "C:/python/python.exe"))); setup.settings()->set_target_os(Settings::WIN); std::ostringstream out; @@ -124,11 +128,11 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { const char expected_win[] = "arch = environment.x86\n" "rule __foo_bar___rule\n" - " command = $pythonpath gyp-win-tool action-wrapper $arch __foo_bar___rule.$unique_name.rsp\n" + " command = C:/python/python.exe gyp-win-tool action-wrapper $arch __foo_bar___rule.$unique_name.rsp\n" " description = CUSTOM //foo:bar()\n" " restat = 1\n" " rspfile = __foo_bar___rule.$unique_name.rsp\n" - " rspfile_content = $pythonpath ../../foo/script.py -i ${source} \"--out=foo$ bar${source_name_part}.o\"\n" + " rspfile_content = C:/python/python.exe ../../foo/script.py -i ${source} \"--out=foo$ bar${source_name_part}.o\"\n" "\n" "build input1.out: __foo_bar___rule../../foo/input1.txt | ../../foo/included.txt\n" " unique_name = 0\n" diff --git a/tools/gn/ninja_target_writer.cc b/tools/gn/ninja_target_writer.cc index 82a022e..3eccb18 100644 --- a/tools/gn/ninja_target_writer.cc +++ b/tools/gn/ninja_target_writer.cc @@ -79,7 +79,8 @@ void NinjaTargetWriter::RunAndWriteFile(const Target* target) { writer.Run(); } else if (target->output_type() == Target::EXECUTABLE || target->output_type() == Target::STATIC_LIBRARY || - target->output_type() == Target::SHARED_LIBRARY) { + target->output_type() == Target::SHARED_LIBRARY || + target->output_type() == Target::SOURCE_SET) { NinjaBinaryTargetWriter writer(target, file); writer.Run(); } else { diff --git a/tools/gn/output_file.h b/tools/gn/output_file.h index 9c5e4b2..2e7a0ce 100644 --- a/tools/gn/output_file.h +++ b/tools/gn/output_file.h @@ -33,9 +33,12 @@ class OutputFile { bool operator!=(const OutputFile& other) const { return value_ != other.value_; } + bool operator<(const OutputFile& other) const { + return value_ < other.value_; + } private: std::string value_; }; -#endif +#endif // TOOLS_GN_OUTPUT_FILE_H_ diff --git a/tools/gn/secondary/build/config/BUILDCONFIG.gn b/tools/gn/secondary/build/config/BUILDCONFIG.gn index e48f896..d2e609d 100644 --- a/tools/gn/secondary/build/config/BUILDCONFIG.gn +++ b/tools/gn/secondary/build/config/BUILDCONFIG.gn @@ -162,7 +162,7 @@ set_sources_assignment_filter(sources_assignment_filter) if (is_component_build) { component_mode = "shared_library" } else { - component_mode = "static_library" + component_mode = "source_set" } toolkit_uses_gtk = is_linux @@ -266,6 +266,10 @@ set_defaults("shared_library") { } } +set_defaults("source_set") { + configs = native_compiler_configs +} + # ============================================================================== # TOOLCHAIN SETUP # ============================================================================== diff --git a/tools/gn/secondary/build/toolchain/nacl/BUILD.gn b/tools/gn/secondary/build/toolchain/nacl/BUILD.gn index 2e2fc7f..b5fe248 100644 --- a/tools/gn/secondary/build/toolchain/nacl/BUILD.gn +++ b/tools/gn/secondary/build/toolchain/nacl/BUILD.gn @@ -38,6 +38,18 @@ toolchain("x86_newlib") { #pool = "link_pool" } + if (is_win) { + tool("stamp") { + command = "$python_path gyp-win-tool stamp \$out" + description = "STAMP \$out" + } + } else { + tool("stamp") { + command = "touch \$out" + description = "STAMP \$out" + } + } + toolchain_args() { is_nacl = true diff --git a/tools/gn/secondary/chrome/BUILD.gn b/tools/gn/secondary/chrome/BUILD.gn index 133bf82..4e6df28 100644 --- a/tools/gn/secondary/chrome/BUILD.gn +++ b/tools/gn/secondary/chrome/BUILD.gn @@ -96,7 +96,7 @@ static_library("common") { } # TODO(brettw) move to browser/devtools/BUILD.gn -static_library("debugger") { +source_set("debugger") { sources = [ "browser/devtools/adb/android_rsa.cc", "browser/devtools/adb/android_rsa.h", @@ -167,15 +167,15 @@ static_library("debugger") { } -static_library("plugin") { +source_set("plugin") { external = true } -static_library("renderer") { +source_set("renderer") { external = true } -static_library("utility") { +source_set("utility") { external = true } diff --git a/tools/gn/target.cc b/tools/gn/target.cc index ec35a05..a380156 100644 --- a/tools/gn/target.cc +++ b/tools/gn/target.cc @@ -188,7 +188,8 @@ void Target::PullDependentTargetInfo(std::set<const Config*>* unique_configs) { // Direct dependent libraries. if (dep->output_type() == STATIC_LIBRARY || - dep->output_type() == SHARED_LIBRARY) + dep->output_type() == SHARED_LIBRARY || + dep->output_type() == SOURCE_SET) inherited_libraries_.insert(dep); // Inherited libraries and flags are inherited across static library diff --git a/tools/gn/target.h b/tools/gn/target.h index 92e8fe0..1bb51a6 100644 --- a/tools/gn/target.h +++ b/tools/gn/target.h @@ -32,6 +32,7 @@ class Target : public Item { EXECUTABLE, SHARED_LIBRARY, STATIC_LIBRARY, + SOURCE_SET, COPY_FILES, CUSTOM, }; @@ -175,9 +176,9 @@ class Target : public Item { bool external_; - // Libraries from transitive deps. Libraries need to be linked only - // with the end target (executable, shared library). These do not get - // pushed beyond shared library boundaries. + // Static libraries and source sets from transitive deps. These things need + // to be linked only with the end target (executable, shared library). These + // do not get pushed beyond shared library boundaries. std::set<const Target*> inherited_libraries_; // These libs and dirs are inherited from statically linked deps and all diff --git a/tools/gn/target_generator.cc b/tools/gn/target_generator.cc index b32bbe1..f32245a 100644 --- a/tools/gn/target_generator.cc +++ b/tools/gn/target_generator.cc @@ -100,6 +100,10 @@ void TargetGenerator::GenerateTarget(Scope* scope, BinaryTargetGenerator generator(target, scope, function_token, Target::SHARED_LIBRARY, err); generator.Run(); + } else if (output_type == functions::kSourceSet) { + BinaryTargetGenerator generator(target, scope, function_token, + Target::SOURCE_SET, err); + generator.Run(); } else if (output_type == functions::kStaticLibrary) { BinaryTargetGenerator generator(target, scope, function_token, Target::STATIC_LIBRARY, err); |