diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-17 19:20:26 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-17 19:20:26 +0000 |
commit | cc11ecf999d641fb632399348e5f08a18086ee2d (patch) | |
tree | 643b9f07d4db2f9aacc7081febcf179eb5ed1b90 /tools | |
parent | baf7a12f090c7c0a9a49d11e70ee1e5f0564c46b (diff) | |
download | chromium_src-cc11ecf999d641fb632399348e5f08a18086ee2d.zip chromium_src-cc11ecf999d641fb632399348e5f08a18086ee2d.tar.gz chromium_src-cc11ecf999d641fb632399348e5f08a18086ee2d.tar.bz2 |
Linux GYP generator for GN.
The Linux generator needs to be different than the Windows one since it supports cross-compiles. However, Windows doesn't support the conditions based on the toolset.
This doesn't actually hook up the cross-compile yet. Currently it passes null for the host targets. I'll do that in a future pass.
To make this formatted correctly, I redid how the indenting worked in the GYP output code.
R=scottmg@chromium.org
Review URL: https://codereview.chromium.org/27563003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229200 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gn/command_gyp.cc | 9 | ||||
-rw-r--r-- | tools/gn/gyp_binary_target_writer.cc | 235 | ||||
-rw-r--r-- | tools/gn/gyp_binary_target_writer.h | 31 | ||||
-rw-r--r-- | tools/gn/gyp_target_writer.cc | 2 |
4 files changed, 206 insertions, 71 deletions
diff --git a/tools/gn/command_gyp.cc b/tools/gn/command_gyp.cc index 9c00513..226525c 100644 --- a/tools/gn/command_gyp.cc +++ b/tools/gn/command_gyp.cc @@ -197,15 +197,16 @@ Scope::KeyValueMap GetArgsFromGypDefines() { Scope::KeyValueMap result; + static const char kIsComponentBuild[] = "is_component_build"; if (gyp_defines["component"] == "shared_library") { - result["is_component_build"] = Value(NULL, true); + result[kIsComponentBuild] = Value(NULL, true); } else { - result["is_component_build"] = Value(NULL, false); + result[kIsComponentBuild] = Value(NULL, false); } // Windows SDK path. GYP and the GN build use the same name. - const char kWinSdkPath[] = "windows_sdk_path"; - if (gyp_defines[kWinSdkPath].empty()) + static const char kWinSdkPath[] = "windows_sdk_path"; + if (!gyp_defines[kWinSdkPath].empty()) result[kWinSdkPath] = Value(NULL, gyp_defines[kWinSdkPath]); return result; diff --git a/tools/gn/gyp_binary_target_writer.cc b/tools/gn/gyp_binary_target_writer.cc index 8cc0e6c..3efab7e 100644 --- a/tools/gn/gyp_binary_target_writer.cc +++ b/tools/gn/gyp_binary_target_writer.cc @@ -6,6 +6,7 @@ #include <set> +#include "base/logging.h" #include "tools/gn/config_values_extractors.h" #include "tools/gn/err.h" #include "tools/gn/escape.h" @@ -100,46 +101,57 @@ std::string GetVCOptimization(std::vector<std::string>* cflags) { return "'2'"; // Default value. } +const int kExtraIndent = 2; + } // namespace GypBinaryTargetWriter::GypBinaryTargetWriter(const Target* debug_target, const Target* release_target, + const Target* debug_host_target, + const Target* release_host_target, std::ostream& out) : GypTargetWriter(debug_target, out), - release_target_(release_target) { + release_target_(release_target), + debug_host_target_(debug_host_target), + release_host_target_(release_host_target) { } GypBinaryTargetWriter::~GypBinaryTargetWriter() { } void GypBinaryTargetWriter::Run() { - out_ << " {\n"; - - WriteName(); - WriteType(); - - out_ << " 'configurations': {\n"; - out_ << " 'Debug': {\n"; - WriteFlags(target_); - out_ << " },\n"; - out_ << " 'Release': {\n"; - WriteFlags(release_target_); - out_ << " },\n"; - out_ << " 'Debug_x64': {},\n"; - out_ << " 'Release_x64': {},\n"; - out_ << " },\n"; - - WriteSources(); - WriteDeps(); - - out_ << " },\n"; + int indent = 4; + + Indent(indent) << "{\n"; + + WriteName(indent + kExtraIndent); + WriteType(indent + kExtraIndent); + + if (target_->settings()->IsLinux()) { + WriteLinuxConfiguration(indent + kExtraIndent); + } else if (target_->settings()->IsWin()) { + WriteVCConfiguration(indent + kExtraIndent); + } else if (target_->settings()->IsMac()) { + // TODO(brettw) mac. + NOTREACHED(); + //WriteMacConfiguration(); + } + + Indent(indent) << "},\n"; } -void GypBinaryTargetWriter::WriteName() { +std::ostream& GypBinaryTargetWriter::Indent(int spaces) { + const char kSpaces[81] = + " " + " "; + CHECK(spaces == arraysize(kSpaces) - 1); + out_.write(kSpaces, spaces); + return out_; +} + +void GypBinaryTargetWriter::WriteName(int indent) { std::string name = helper_.GetNameForTarget(target_); - out_ << " 'target_name': '"; - out_ << name; - out_ << "',\n"; + Indent(indent) << "'target_name': '" << name << "',\n"; std::string product_name; if (target_->output_name().empty()) @@ -151,11 +163,11 @@ void GypBinaryTargetWriter::WriteName() { // another "lib" on Linux, but GYP doesn't. We need to rename applicable // targets here. - out_ << " 'product_name': '" << product_name << "',\n"; + Indent(indent) << "'product_name': '" << product_name << "',\n"; } -void GypBinaryTargetWriter::WriteType() { - out_ << " 'type': "; +void GypBinaryTargetWriter::WriteType(int indent) { + Indent(indent) << "'type': "; switch (target_->output_type()) { case Target::EXECUTABLE: out_ << "'executable',\n"; @@ -174,34 +186,47 @@ void GypBinaryTargetWriter::WriteType() { } if (target_->hard_dep()) - out_ << " 'hard_dependency': 1,\n"; + Indent(indent) << "'hard_dependency': 1,\n"; } -void GypBinaryTargetWriter::WriteFlags(const Target* target) { - WriteDefines(target); - WriteIncludes(target); - if (target->settings()->IsWin()) - WriteVCFlags(target); +void GypBinaryTargetWriter::WriteVCConfiguration(int indent) { + Indent(indent) << "'configurations': {\n"; + Indent(indent + kExtraIndent) << "'Debug': {\n"; + WriteDefines(target_, indent + kExtraIndent * 2); + WriteIncludes(target_, indent + kExtraIndent * 2); + WriteVCFlags(target_, indent + kExtraIndent * 2); + Indent(indent + kExtraIndent) << "},\n"; + Indent(indent + kExtraIndent) << "'Release': {\n"; + WriteDefines(release_target_, indent + kExtraIndent * 2); + WriteIncludes(release_target_, indent + kExtraIndent * 2); + WriteVCFlags(release_target_, indent + kExtraIndent * 2); + Indent(indent + kExtraIndent) << "},\n"; + Indent(indent + kExtraIndent) << "'Debug_x64': {},\n"; + Indent(indent + kExtraIndent) << "'Release_x64': {},\n"; + Indent(indent) << "},\n"; + + WriteSources(target_, indent); + WriteDeps(target_, indent); } -void GypBinaryTargetWriter::WriteDefines(const Target* target) { - out_ << " 'defines': ["; +void GypBinaryTargetWriter::WriteDefines(const Target* target, int indent) { + Indent(indent) << "'defines': ["; RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::defines, StringWriter(), out_); out_ << " ],\n"; } -void GypBinaryTargetWriter::WriteIncludes(const Target* target) { - out_ << " 'include_dirs': ["; +void GypBinaryTargetWriter::WriteIncludes(const Target* target, int indent) { + Indent(indent) << "'include_dirs': ["; RecursiveTargetConfigToStream<SourceDir>(target, &ConfigValues::include_dirs, IncludeWriter(helper_), out_); out_ << " ],\n"; } -void GypBinaryTargetWriter::WriteVCFlags(const Target* target) { +void GypBinaryTargetWriter::WriteVCFlags(const Target* target, int indent) { // C flags. - out_ << " 'msvs_settings': {\n"; - out_ << " 'VCCLCompilerTool': {\n"; + Indent(indent) << "'msvs_settings': {\n"; + Indent(indent + kExtraIndent) << "'VCCLCompilerTool': {\n"; std::vector<std::string> cflags; StringAccumulator acc(&cflags); @@ -213,18 +238,19 @@ void GypBinaryTargetWriter::WriteVCFlags(const Target* target) { std::string optimization = GetVCOptimization(&cflags); WriteArray(out_, "AdditionalOptions", cflags, 14); // TODO(brettw) cflags_c and cflags_cc! - out_ << " 'Optimization': " << optimization << ",\n"; - out_ << " },\n"; + Indent(indent + kExtraIndent * 2) << "'Optimization': " + << optimization << ",\n"; + Indent(indent + kExtraIndent) << "},\n"; // Linker tool stuff. - out_ << " 'VCLinkerTool': {\n"; + Indent(indent + kExtraIndent) << "'VCLinkerTool': {\n"; // ...Library dirs. EscapeOptions escape_options; escape_options.mode = ESCAPE_JSON; const OrderedSet<SourceDir> all_lib_dirs = target->all_lib_dirs(); if (!all_lib_dirs.empty()) { - out_ << " 'AdditionalLibraryDirectories': ["; + Indent(indent + kExtraIndent * 2) << "'AdditionalLibraryDirectories': ["; for (size_t i = 0; i < all_lib_dirs.size(); i++) { out_ << " '"; EscapeStringToStream(out_, @@ -238,7 +264,7 @@ void GypBinaryTargetWriter::WriteVCFlags(const Target* target) { // ...Libraries. const OrderedSet<std::string> all_libs = target->all_libs(); if (!all_libs.empty()) { - out_ << " 'AdditionalDependencies': ["; + Indent(indent + kExtraIndent * 2) << "'AdditionalDependencies': ["; for (size_t i = 0; i < all_libs.size(); i++) { out_ << " '"; EscapeStringToStream(out_, all_libs[i], escape_options); @@ -255,37 +281,130 @@ void GypBinaryTargetWriter::WriteVCFlags(const Target* target) { RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::ldflags, acc, out_); WriteArray(out_, "AdditionalOptions", ldflags, 14); - out_ << " },\n"; + Indent(indent + kExtraIndent) << "},\n"; + Indent(indent) << "},\n"; +} + +void GypBinaryTargetWriter::WriteLinuxConfiguration(int indent) { + // The Linux stuff works differently. On Linux we support cross-compiles and + // all ninja generators know to look for target conditions. Other platforms' + // generators don't all do this, so we can't have the same GYP structure. + Indent(indent) << "'target_conditions': [\n"; + // The host toolset is configured for the current computer, we will only have + // this when doing cross-compiles. + if (debug_host_target_ && release_host_target_) { + Indent(indent + kExtraIndent) << "['_toolset == \"host\"', {\n"; + Indent(indent + kExtraIndent * 2) << "'configurations': {\n"; + Indent(indent + kExtraIndent * 3) << "'Debug': {\n"; + WriteDefines(debug_host_target_, indent + kExtraIndent * 4); + WriteIncludes(debug_host_target_, indent + kExtraIndent * 4); + WriteLinuxFlags(debug_host_target_, indent + kExtraIndent * 4); + Indent(indent + kExtraIndent * 3) << "},\n"; + Indent(indent + kExtraIndent * 3) << "'Release': {\n"; + WriteDefines(release_host_target_, indent + kExtraIndent * 4); + WriteIncludes(release_host_target_, indent + kExtraIndent * 4); + WriteLinuxFlags(release_host_target_, indent + kExtraIndent * 4); + Indent(indent + kExtraIndent * 3) << "},\n"; + Indent(indent + kExtraIndent * 2) << "}\n"; + + // The sources and deps are per-toolset but shared between debug & release. + WriteSources(debug_host_target_, indent + kExtraIndent * 2); + + Indent(indent + kExtraIndent) << "],\n"; + } + + // The target toolset is the "regular" one. + Indent(indent + kExtraIndent) << "['_toolset == \"target\"', {\n"; + Indent(indent + kExtraIndent * 2) << "'configurations': {\n"; + Indent(indent + kExtraIndent * 3) << "'Debug': {\n"; + WriteDefines(target_, indent + kExtraIndent * 4); + WriteIncludes(target_, indent + kExtraIndent * 4); + WriteLinuxFlags(target_, indent + kExtraIndent * 4); + Indent(indent + kExtraIndent * 3) << "},\n"; + Indent(indent + kExtraIndent * 3) << "'Release': {\n"; + WriteDefines(release_target_, indent + kExtraIndent * 4); + WriteIncludes(release_target_, indent + kExtraIndent * 4); + WriteLinuxFlags(release_target_, indent + kExtraIndent * 4); + Indent(indent + kExtraIndent * 3) << "},\n"; + Indent(indent + kExtraIndent * 2) << "},\n"; + + WriteSources(target_, indent + kExtraIndent * 2); + + Indent(indent + kExtraIndent) << "},],\n"; + Indent(indent) << "],\n"; + + // TODO(brettw) The deps can probably vary based on the toolset. However, + // GYP doesn't seem to properly expand the deps when we put this inside the + // toolset condition above. Either we need to decide the deps never vary, or + // make it work in the conditions above. + WriteDeps(target_, indent); +} - out_ << " },\n"; +void GypBinaryTargetWriter::WriteLinuxFlags(const Target* target, int indent) { +#define WRITE_FLAGS(name) \ + Indent(indent) << "'" #name "': ["; \ + RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::name, \ + StringWriter(), out_); \ + out_ << " ],\n"; + WRITE_FLAGS(cflags) + WRITE_FLAGS(cflags_c) + WRITE_FLAGS(cflags_cc) + WRITE_FLAGS(cflags_objc) + WRITE_FLAGS(cflags_objcc) +#undef WRITE_FLAGS + + // Put libraries and library directories in with ldflags. + Indent(indent) << "'ldflags': ["; \ + RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::ldflags, + StringWriter(), out_); + + EscapeOptions escape_options; + escape_options.mode = ESCAPE_JSON; + const OrderedSet<SourceDir> all_lib_dirs = target->all_lib_dirs(); + for (size_t i = 0; i < all_lib_dirs.size(); i++) { + out_ << " '-L"; + EscapeStringToStream(out_, + helper_.GetDirReference(all_lib_dirs[i], false), + escape_options); + out_ << "',"; + } + + const OrderedSet<std::string> all_libs = target->all_libs(); + for (size_t i = 0; i < all_libs.size(); i++) { + out_ << " '-l"; + EscapeStringToStream(out_, all_libs[i], escape_options); + out_ << "',"; + } + out_ << " ],\n"; } -void GypBinaryTargetWriter::WriteSources() { - out_ << " 'sources': [\n"; +void GypBinaryTargetWriter::WriteSources(const Target* target, int indent) { + Indent(indent) << "'sources': [\n"; - const Target::FileList& sources = target_->sources(); + const Target::FileList& sources = target->sources(); for (size_t i = 0; i < sources.size(); i++) { const SourceFile& input_file = sources[i]; - out_ << " '" << helper_.GetFileReference(input_file) << "',\n"; + Indent(indent + kExtraIndent) << "'" << helper_.GetFileReference(input_file) + << "',\n"; } - out_ << " ],\n"; + Indent(indent) << "],\n"; } -void GypBinaryTargetWriter::WriteDeps() { - const std::vector<const Target*>& deps = target_->deps(); +void GypBinaryTargetWriter::WriteDeps(const Target* target, int indent) { + const std::vector<const Target*>& deps = target->deps(); if (deps.empty()) return; EscapeOptions escape_options; escape_options.mode = ESCAPE_JSON; - out_ << " 'dependencies': [\n"; + Indent(indent) << "'dependencies': [\n"; for (size_t i = 0; i < deps.size(); i++) { - out_ << " '"; + Indent(indent + kExtraIndent) << "'"; EscapeStringToStream(out_, helper_.GetFullRefForTarget(deps[i]), escape_options); out_ << "',\n"; } - out_ << " ],\n"; + Indent(indent) << "],\n"; } diff --git a/tools/gn/gyp_binary_target_writer.h b/tools/gn/gyp_binary_target_writer.h index 625a306..eaf2566 100644 --- a/tools/gn/gyp_binary_target_writer.h +++ b/tools/gn/gyp_binary_target_writer.h @@ -18,28 +18,43 @@ class GypBinaryTargetWriter : public GypTargetWriter { public: GypBinaryTargetWriter(const Target* debug_target, const Target* release_target, + const Target* debug_host_target, + const Target* release_host_target, std::ostream& out); virtual ~GypBinaryTargetWriter(); virtual void Run() OVERRIDE; private: - void WriteName(); - void WriteType(); + // Writes the given number of spaces to the output stream and returns it. + std::ostream& Indent(int spaces); + + void WriteName(int indent); + void WriteType(int indent); // The flags can vary between debug and release, so we must pass in the // correct debug or release target to the functions. - void WriteFlags(const Target* target); - void WriteDefines(const Target* target); - void WriteIncludes(const Target* target); - void WriteVCFlags(const Target* target); + void WriteDefines(const Target* target, int indent); + void WriteIncludes(const Target* target, int indent); + + // For writing VisualStudio flags. + void WriteVCConfiguration(int indent); + void WriteVCFlags(const Target* target, int indent); - void WriteSources(); - void WriteDeps(); + void WriteLinuxConfiguration(int indent); + void WriteLinuxFlags(const Target* target, int indent); + + void WriteSources(const Target* target, int indent); + void WriteDeps(const Target* target, int indent); // The normal |target_| in the base class stores the debug version. const Target* release_target_; + // When doing cross-compiles (Linux-only) these will be the host version of + // the target, if any (may be null). + const Target* debug_host_target_; + const Target* release_host_target_; + DISALLOW_COPY_AND_ASSIGN(GypBinaryTargetWriter); }; diff --git a/tools/gn/gyp_target_writer.cc b/tools/gn/gyp_target_writer.cc index eec2b89..ea431fd 100644 --- a/tools/gn/gyp_target_writer.cc +++ b/tools/gn/gyp_target_writer.cc @@ -50,7 +50,7 @@ void GypTargetWriter::WriteFile(const SourceFile& gyp_file, case Target::SHARED_LIBRARY: case Target::SOURCE_SET: { GypBinaryTargetWriter writer(targets[i].debug, targets[i].release, - file); + NULL, NULL, file); writer.Run(); break; } |