diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-19 22:52:16 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-19 22:54:04 +0000 |
commit | 0dfcae783a9285e3a3099f7098f076ef7b093f6e (patch) | |
tree | 543118667a7393e30934ae7c14050d4686219657 /tools/gn/ninja_toolchain_writer.cc | |
parent | c9a47cccedaa0556b52c1ceeb6c6a0d0b2f018f9 (diff) | |
download | chromium_src-0dfcae783a9285e3a3099f7098f076ef7b093f6e.zip chromium_src-0dfcae783a9285e3a3099f7098f076ef7b093f6e.tar.gz chromium_src-0dfcae783a9285e3a3099f7098f076ef7b093f6e.tar.bz2 |
Support more configurability in GN toolchains
This uses substitution patterns in toolchains to allow the toolchain to specify more flexibly how files are to be named and generated at each step. The toolchain now has control over the naming of object and executable files, for example, where before these were hardcoded.
This removes most of the OS-specific logic hardcoded into the GN tool. There is still a bunch in action invocation; this will be done in a followup.
R=jamesr@chromium.org
Review URL: https://codereview.chromium.org/440333002
Cr-Commit-Position: refs/heads/master@{#290685}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290685 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/gn/ninja_toolchain_writer.cc')
-rw-r--r-- | tools/gn/ninja_toolchain_writer.cc | 93 |
1 files changed, 61 insertions, 32 deletions
diff --git a/tools/gn/ninja_toolchain_writer.cc b/tools/gn/ninja_toolchain_writer.cc index dac5921..ae2b6c9 100644 --- a/tools/gn/ninja_toolchain_writer.cc +++ b/tools/gn/ninja_toolchain_writer.cc @@ -9,11 +9,20 @@ #include "base/file_util.h" #include "base/strings/stringize_macros.h" #include "tools/gn/build_settings.h" +#include "tools/gn/filesystem_utils.h" +#include "tools/gn/ninja_utils.h" #include "tools/gn/settings.h" +#include "tools/gn/substitution_writer.h" #include "tools/gn/target.h" #include "tools/gn/toolchain.h" #include "tools/gn/trace.h" +namespace { + +const char kIndent[] = " "; + +} // namespace + NinjaToolchainWriter::NinjaToolchainWriter( const Settings* settings, const Toolchain* toolchain, @@ -23,8 +32,7 @@ NinjaToolchainWriter::NinjaToolchainWriter( toolchain_(toolchain), targets_(targets), out_(out), - path_output_(settings_->build_settings()->build_dir(), ESCAPE_NINJA), - helper_(settings->build_settings()) { + path_output_(settings_->build_settings()->build_dir(), ESCAPE_NINJA) { } NinjaToolchainWriter::~NinjaToolchainWriter() { @@ -40,10 +48,8 @@ bool NinjaToolchainWriter::RunAndWriteFile( const Settings* settings, const Toolchain* toolchain, const std::vector<const Target*>& targets) { - NinjaHelper helper(settings->build_settings()); base::FilePath ninja_file(settings->build_settings()->GetFullPath( - helper.GetNinjaFileForToolchain(settings).GetSourceFile( - settings->build_settings()))); + GetNinjaFileForToolchain(settings))); ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, FilePathToUTF8(ninja_file)); base::CreateDirectory(ninja_file.DirName()); @@ -60,43 +66,66 @@ bool NinjaToolchainWriter::RunAndWriteFile( } void NinjaToolchainWriter::WriteRules() { - std::string indent(" "); - - NinjaHelper helper(settings_->build_settings()); - std::string rule_prefix = helper.GetRulePrefix(settings_); + std::string rule_prefix = GetNinjaRulePrefixForToolchain(settings_); for (int i = Toolchain::TYPE_NONE + 1; i < Toolchain::TYPE_NUMTYPES; i++) { Toolchain::ToolType tool_type = static_cast<Toolchain::ToolType>(i); - const Toolchain::Tool& tool = toolchain_->GetTool(tool_type); - if (tool.command.empty()) - continue; - - out_ << "rule " << rule_prefix << Toolchain::ToolTypeToName(tool_type) - << std::endl; - - #define WRITE_ARG(name) \ - if (!tool.name.empty()) \ - out_ << indent << " " STRINGIZE(name) " = " << tool.name << std::endl; - WRITE_ARG(command); - WRITE_ARG(depfile); - WRITE_ARG(description); - WRITE_ARG(pool); - WRITE_ARG(restat); - WRITE_ARG(rspfile); - WRITE_ARG(rspfile_content); - #undef WRITE_ARG - - // Deps is called "depsformat" in GN to avoid confusion with dependencies. - if (!tool.depsformat.empty()) \ - out_ << indent << " deps = " << tool.depsformat << std::endl; + const Tool* tool = toolchain_->GetTool(tool_type); + if (tool) + WriteToolRule(tool_type, tool, rule_prefix); } out_ << std::endl; } +void NinjaToolchainWriter::WriteToolRule(const Toolchain::ToolType type, + const Tool* tool, + const std::string& rule_prefix) { + out_ << "rule " << rule_prefix << Toolchain::ToolTypeToName(type) + << std::endl; + + // Rules explicitly include shell commands, so don't try to escape. + EscapeOptions options; + options.mode = ESCAPE_NINJA_PREFORMATTED_COMMAND; + + CHECK(!tool->command().empty()) << "Command should not be empty"; + WriteRulePattern("command", tool->command(), options); + + WriteRulePattern("description", tool->description(), options); + WriteRulePattern("rspfile", tool->rspfile(), options); + WriteRulePattern("rspfile_content", tool->rspfile_content(), options); + + if (tool->depsformat() == Tool::DEPS_GCC) { + // GCC-style deps require a depfile. + if (!tool->depfile().empty()) { + WriteRulePattern("depfile", tool->depfile(), options); + out_ << kIndent << "deps = gcc" << std::endl; + } + } else if (tool->depsformat() == Tool::DEPS_MSVC) { + // MSVC deps don't have a depfile. + out_ << kIndent << "deps = msvc" << std::endl; + } + + if (!tool->pool().empty()) + out_ << kIndent << "pool = " << tool->pool() << std::endl; + if (tool->restat()) + out_ << kIndent << "restat = 1" << std::endl; +} + +void NinjaToolchainWriter::WriteRulePattern(const char* name, + const SubstitutionPattern& pattern, + const EscapeOptions& options) { + if (pattern.empty()) + return; + out_ << kIndent << name << " = "; + SubstitutionWriter::WriteWithNinjaVariables(pattern, options, out_); + out_ << std::endl; +} + void NinjaToolchainWriter::WriteSubninjas() { // Write subninja commands for each generated target. for (size_t i = 0; i < targets_.size(); i++) { - OutputFile ninja_file = helper_.GetNinjaFileForTarget(targets_[i]); + OutputFile ninja_file(targets_[i]->settings()->build_settings(), + GetNinjaFileForTarget(targets_[i])); out_ << "subninja "; path_output_.WriteFile(out_, ninja_file); out_ << std::endl; |