Index: tools/gn/ninja_target_writer.cc |
diff --git a/tools/gn/ninja_target_writer.cc b/tools/gn/ninja_target_writer.cc |
index ade81a0fd9291ebc43be2e8349099ec7d9bec59d..fd36a304caae82c367749ac90505572bd2128d8c 100644 |
--- a/tools/gn/ninja_target_writer.cc |
+++ b/tools/gn/ninja_target_writer.cc |
@@ -8,43 +8,41 @@ |
#include <sstream> |
#include "base/file_util.h" |
+#include "base/strings/string_util.h" |
#include "tools/gn/err.h" |
+#include "tools/gn/filesystem_utils.h" |
#include "tools/gn/ninja_action_target_writer.h" |
#include "tools/gn/ninja_binary_target_writer.h" |
#include "tools/gn/ninja_copy_target_writer.h" |
#include "tools/gn/ninja_group_target_writer.h" |
+#include "tools/gn/ninja_utils.h" |
#include "tools/gn/scheduler.h" |
#include "tools/gn/string_utils.h" |
+#include "tools/gn/substitution_writer.h" |
#include "tools/gn/target.h" |
#include "tools/gn/trace.h" |
NinjaTargetWriter::NinjaTargetWriter(const Target* target, |
- const Toolchain* toolchain, |
std::ostream& out) |
: settings_(target->settings()), |
target_(target), |
- toolchain_(toolchain), |
out_(out), |
- path_output_(settings_->build_settings()->build_dir(), ESCAPE_NINJA), |
- helper_(settings_->build_settings()) { |
+ path_output_(settings_->build_settings()->build_dir(), ESCAPE_NINJA) { |
} |
NinjaTargetWriter::~NinjaTargetWriter() { |
} |
// static |
-void NinjaTargetWriter::RunAndWriteFile(const Target* target, |
- const Toolchain* toolchain) { |
+void NinjaTargetWriter::RunAndWriteFile(const Target* target) { |
const Settings* settings = target->settings(); |
- NinjaHelper helper(settings->build_settings()); |
ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, |
target->label().GetUserVisibleName(false)); |
trace.SetToolchain(settings->toolchain_label()); |
base::FilePath ninja_file(settings->build_settings()->GetFullPath( |
- helper.GetNinjaFileForTarget(target).GetSourceFile( |
- settings->build_settings()))); |
+ GetNinjaFileForTarget(target))); |
if (g_scheduler->verbose_logging()) |
g_scheduler->Log("Writing", FilePathToUTF8(ninja_file)); |
@@ -57,20 +55,20 @@ void NinjaTargetWriter::RunAndWriteFile(const Target* target, |
// Call out to the correct sub-type of writer. |
if (target->output_type() == Target::COPY_FILES) { |
- NinjaCopyTargetWriter writer(target, toolchain, file); |
+ NinjaCopyTargetWriter writer(target, file); |
writer.Run(); |
} else if (target->output_type() == Target::ACTION || |
target->output_type() == Target::ACTION_FOREACH) { |
- NinjaActionTargetWriter writer(target, toolchain, file); |
+ NinjaActionTargetWriter writer(target, file); |
writer.Run(); |
} else if (target->output_type() == Target::GROUP) { |
- NinjaGroupTargetWriter writer(target, toolchain, file); |
+ NinjaGroupTargetWriter writer(target, file); |
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::SOURCE_SET) { |
- NinjaBinaryTargetWriter writer(target, toolchain, file); |
+ NinjaBinaryTargetWriter writer(target, file); |
writer.Run(); |
} else { |
CHECK(0); |
@@ -81,8 +79,75 @@ void NinjaTargetWriter::RunAndWriteFile(const Target* target, |
static_cast<int>(contents.size())); |
} |
+void NinjaTargetWriter::WriteSharedVars(const SubstitutionBits& bits) { |
+ bool written_anything = false; |
+ |
+ // Target label. |
+ if (bits.used[SUBSTITUTION_LABEL]) { |
+ out_ << kSubstitutionNinjaNames[SUBSTITUTION_LABEL] << " = " |
+ << SubstitutionWriter::GetTargetSubstitution( |
+ target_, SUBSTITUTION_LABEL) |
+ << std::endl; |
+ written_anything = true; |
+ } |
+ |
+ // Root gen dir. |
+ if (bits.used[SUBSTITUTION_ROOT_GEN_DIR]) { |
+ out_ << kSubstitutionNinjaNames[SUBSTITUTION_ROOT_GEN_DIR] << " = " |
+ << SubstitutionWriter::GetTargetSubstitution( |
+ target_, SUBSTITUTION_ROOT_GEN_DIR) |
+ << std::endl; |
+ written_anything = true; |
+ } |
+ |
+ // Root out dir. |
+ if (bits.used[SUBSTITUTION_ROOT_OUT_DIR]) { |
+ out_ << kSubstitutionNinjaNames[SUBSTITUTION_ROOT_OUT_DIR] << " = " |
+ << SubstitutionWriter::GetTargetSubstitution( |
+ target_, SUBSTITUTION_ROOT_OUT_DIR) |
+ << std::endl; |
+ written_anything = true; |
+ } |
+ |
+ // Target gen dir. |
+ if (bits.used[SUBSTITUTION_TARGET_GEN_DIR]) { |
+ out_ << kSubstitutionNinjaNames[SUBSTITUTION_TARGET_GEN_DIR] << " = " |
+ << SubstitutionWriter::GetTargetSubstitution( |
+ target_, SUBSTITUTION_TARGET_GEN_DIR) |
+ << std::endl; |
+ written_anything = true; |
+ } |
+ |
+ // Target out dir. |
+ if (bits.used[SUBSTITUTION_TARGET_OUT_DIR]) { |
+ out_ << kSubstitutionNinjaNames[SUBSTITUTION_TARGET_OUT_DIR] << " = " |
+ << SubstitutionWriter::GetTargetSubstitution( |
+ target_, SUBSTITUTION_TARGET_OUT_DIR) |
+ << std::endl; |
+ written_anything = true; |
+ } |
+ |
+ // Target output name. |
+ if (bits.used[SUBSTITUTION_TARGET_OUTPUT_NAME]) { |
+ out_ << kSubstitutionNinjaNames[SUBSTITUTION_TARGET_OUTPUT_NAME] << " = " |
+ << SubstitutionWriter::GetTargetSubstitution( |
+ target_, SUBSTITUTION_TARGET_OUTPUT_NAME) |
+ << std::endl; |
+ written_anything = true; |
+ } |
+ |
+ // If we wrote any vars, separate them from the rest of the file that follows |
+ // with a blank line. |
+ if (written_anything) |
+ out_ << std::endl; |
+} |
+ |
std::string NinjaTargetWriter::WriteInputDepsStampAndGetDep( |
const std::vector<const Target*>& extra_hard_deps) const { |
+ CHECK(target_->toolchain()) |
+ << "Toolchain not set on target " |
+ << target_->label().GetUserVisibleName(true); |
+ |
// For an action (where we run a script only once) the sources are the same |
// as the source prereqs. |
bool list_sources_as_input_deps = (target_->output_type() == Target::ACTION); |
@@ -97,7 +162,7 @@ std::string NinjaTargetWriter::WriteInputDepsStampAndGetDep( |
target_->inputs().empty() && |
target_->recursive_hard_deps().empty() && |
(!list_sources_as_input_deps || target_->sources().empty()) && |
- toolchain_->deps().empty()) |
+ target_->toolchain()->deps().empty()) |
return std::string(); // No input/hard deps. |
// One potential optimization is if there are few input dependencies (or |
@@ -107,7 +172,9 @@ std::string NinjaTargetWriter::WriteInputDepsStampAndGetDep( |
// source file can really explode the ninja file but this won't be the most |
// optimal thing in all cases. |
- OutputFile input_stamp_file = helper_.GetTargetOutputDir(target_); |
+ OutputFile input_stamp_file( |
+ RebaseSourceAbsolutePath(GetTargetOutputDir(target_).value(), |
+ settings_->build_settings()->build_dir())); |
input_stamp_file.value().append(target_->label().name()); |
input_stamp_file.value().append(".inputdeps.stamp"); |
@@ -115,8 +182,9 @@ std::string NinjaTargetWriter::WriteInputDepsStampAndGetDep( |
path_output_.WriteFile(stamp_file_stream, input_stamp_file); |
std::string stamp_file_string = stamp_file_stream.str(); |
- out_ << "build " << stamp_file_string << ": " + |
- helper_.GetRulePrefix(settings_) + "stamp"; |
+ out_ << "build " << stamp_file_string << ": " |
+ << GetNinjaRulePrefixForToolchain(settings_) |
+ << Toolchain::ToolTypeToName(Toolchain::TYPE_STAMP); |
// Script file (if applicable). |
if (add_script_source_as_dep) { |
@@ -138,32 +206,60 @@ std::string NinjaTargetWriter::WriteInputDepsStampAndGetDep( |
} |
} |
- // Add on any hard deps that are direct or indirect dependencies. |
+ // The different souces of input deps may duplicate some targets, so uniquify |
+ // them (ordering doesn't matter for this case). |
+ std::set<const Target*> unique_deps; |
+ |
+ // Hard dependencies that are direct or indirect dependencies. |
const std::set<const Target*>& hard_deps = target_->recursive_hard_deps(); |
for (std::set<const Target*>::const_iterator i = hard_deps.begin(); |
- i != hard_deps.end(); ++i) { |
- out_ << " "; |
- path_output_.WriteFile(out_, helper_.GetTargetOutputFile(*i)); |
- } |
+ i != hard_deps.end(); ++i) |
jamesr
2014/08/19 19:30:41
think this gets {} since the for loop is multiline
|
+ unique_deps.insert(*i); |
+ |
+ // Extra hard dependencies passed in. |
+ unique_deps.insert(extra_hard_deps.begin(), extra_hard_deps.end()); |
// Toolchain dependencies. These must be resolved before doing anything. |
// This just writs all toolchain deps for simplicity. If we find that |
// toolchains often have more than one dependency, we could consider writing |
// a toolchain-specific stamp file and only include the stamp here. |
- const LabelTargetVector& toolchain_deps = toolchain_->deps(); |
- for (size_t i = 0; i < toolchain_deps.size(); i++) { |
- out_ << " "; |
- path_output_.WriteFile(out_, |
- helper_.GetTargetOutputFile(toolchain_deps[i].ptr)); |
- } |
+ const LabelTargetVector& toolchain_deps = target_->toolchain()->deps(); |
+ for (size_t i = 0; i < toolchain_deps.size(); i++) |
+ unique_deps.insert(toolchain_deps[i].ptr); |
- // Extra hard deps passed in. |
- for (size_t i = 0; i < extra_hard_deps.size(); i++) { |
+ for (std::set<const Target*>::const_iterator i = unique_deps.begin(); |
+ i != unique_deps.end(); ++i) { |
+ DCHECK(!(*i)->dependency_output_file().value().empty()); |
out_ << " "; |
- path_output_.WriteFile(out_, |
- helper_.GetTargetOutputFile(extra_hard_deps[i])); |
+ path_output_.WriteFile(out_, (*i)->dependency_output_file()); |
} |
out_ << "\n"; |
return " | " + stamp_file_string; |
} |
+ |
+void NinjaTargetWriter::WriteStampForTarget( |
+ const std::vector<OutputFile>& files, |
+ const std::vector<OutputFile>& order_only_deps) { |
+ const OutputFile& stamp_file = target_->dependency_output_file(); |
+ |
+ // First validate that the target's dependency is a stamp file. Otherwise, |
+ // we shouldn't have gotten here! |
+ CHECK(EndsWith(stamp_file.value(), ".stamp", false)) |
+ << "Output should end in \".stamp\" for stamp file output. Instead got: " |
+ << "\"" << stamp_file.value() << "\""; |
+ |
+ out_ << "build "; |
+ path_output_.WriteFile(out_, stamp_file); |
+ |
+ out_ << ": " |
+ << GetNinjaRulePrefixForToolchain(settings_) |
+ << Toolchain::ToolTypeToName(Toolchain::TYPE_STAMP); |
+ path_output_.WriteFiles(out_, files); |
+ |
+ if (!order_only_deps.empty()) { |
+ out_ << " ||"; |
+ path_output_.WriteFiles(out_, order_only_deps); |
+ } |
+ out_ << std::endl; |
+} |