Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Unified Diff: tools/gn/ninja_binary_target_writer.cc

Issue 26267003: Add the concept of a source set to GN. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/gn/ninja_binary_target_writer.h ('k') | tools/gn/ninja_binary_target_writer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/ninja_binary_target_writer.cc
diff --git a/tools/gn/ninja_binary_target_writer.cc b/tools/gn/ninja_binary_target_writer.cc
index 60d3a6a37b40c313afbbb5c78392f60f97af560a..9241021fdcf6c169caa0f0b6ba17b5c8602a91d8 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;
}
« no previous file with comments | « tools/gn/ninja_binary_target_writer.h ('k') | tools/gn/ninja_binary_target_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698