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

Unified Diff: tools/gn/gyp_binary_target_writer.cc

Issue 26561005: GYP generator for 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
Index: tools/gn/gyp_binary_target_writer.cc
diff --git a/tools/gn/gyp_binary_target_writer.cc b/tools/gn/gyp_binary_target_writer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8cc0e6c571b0a64275660471c85e5cafe14db05d
--- /dev/null
+++ b/tools/gn/gyp_binary_target_writer.cc
@@ -0,0 +1,291 @@
+// 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 "tools/gn/gyp_binary_target_writer.h"
+
+#include <set>
+
+#include "tools/gn/config_values_extractors.h"
+#include "tools/gn/err.h"
+#include "tools/gn/escape.h"
+#include "tools/gn/settings.h"
+#include "tools/gn/target.h"
+
+namespace {
+
+// This functor is used to capture the output of RecursiveTargetConfigToStream
+// in an vector.
+struct StringAccumulator {
+ StringAccumulator(std::vector<std::string>* result_in) : result(result_in) {}
+
+ void operator()(const std::string& s, std::ostream&) const {
+ result->push_back(s);
+ }
+
+ std::vector<std::string>* result;
+};
+
+// Writes the given array with the given name. The indent should be the
+// indenting for the name, the values will be indented 2 spaces from there.
+// Writes nothing if there is nothing in the array.
+void WriteArray(std::ostream& out,
+ const char* name,
+ const std::vector<std::string>& values,
+ int indent) {
+ if (values.empty())
+ return;
+
+ EscapeOptions options;
+ options.mode = ESCAPE_JSON;
+
+ std::string indent_str(indent, ' ');
+ out << indent_str << "'" << name << "': [";
+ for (size_t i = 0; i < values.size(); i++) {
+ out << " '";
+ EscapeStringToStream(out, values[i], options);
+ out << "',";
+ }
+ out << " ],\n";
+}
+
+struct StringWriter {
+ StringWriter() {
+ options.mode = ESCAPE_JSON;
+ }
+
+ void operator()(const std::string& s, std::ostream& out) const {
+ out << " '";
+ EscapeStringToStream(out, s, options);
+ out << "',";
+ }
+
+ EscapeOptions options;
+};
+
+struct IncludeWriter {
+ IncludeWriter(const GypHelper& h) : helper(h) {
+ options.mode = ESCAPE_JSON;
+ }
+
+ void operator()(const SourceDir& d, std::ostream& out) const {
+ out << " '";
+ EscapeStringToStream(out, helper.GetDirReference(d, false), options);
+ out << "',";
+ }
+
+ const GypHelper& helper;
+ EscapeOptions options;
+};
+
+// Returns the value from the already-filled in cflags_* for the optimization
+// level to set in the GYP file. Additionally, this removes the flag from the
+// given vector so we don't get duplicates.
+std::string GetVCOptimization(std::vector<std::string>* cflags) {
+ // Searches for the "/O?" option and returns the corresponding GYP value.
+ for (size_t i = 0; i < cflags->size(); i++) {
+ const std::string& cur = (*cflags)[i];
+ if (cur.size() == 3 && cur[0] == '/' && cur[1] == 'O') {
+ char level = cur[2];
+ cflags->erase(cflags->begin() + i); // Invalidates |cur|!
+ switch (level) {
+ case 'd': return "'0'";
+ case '1': return "'1'";
+ case '2': return "'2'";
+ case 'x': return "'3'";
+ default: return "'2'";
+ }
+ }
+ }
+ return "'2'"; // Default value.
+}
+
+} // namespace
+
+GypBinaryTargetWriter::GypBinaryTargetWriter(const Target* debug_target,
+ const Target* release_target,
+ std::ostream& out)
+ : GypTargetWriter(debug_target, out),
+ release_target_(release_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";
+}
+
+void GypBinaryTargetWriter::WriteName() {
+ std::string name = helper_.GetNameForTarget(target_);
+ out_ << " 'target_name': '";
+ out_ << name;
+ out_ << "',\n";
+
+ std::string product_name;
+ if (target_->output_name().empty())
+ product_name = target_->label().name();
+ else
+ product_name = name;
+
+ // TODO(brettw) GN knows not to prefix targets starting with "lib" with
+ // another "lib" on Linux, but GYP doesn't. We need to rename applicable
+ // targets here.
+
+ out_ << " 'product_name': '" << product_name << "',\n";
+}
+
+void GypBinaryTargetWriter::WriteType() {
+ out_ << " 'type': ";
+ switch (target_->output_type()) {
+ case Target::EXECUTABLE:
+ out_ << "'executable',\n";
+ break;
+ case Target::STATIC_LIBRARY:
+ out_ << "'static_library',\n";
+ break;
+ case Target::SHARED_LIBRARY:
+ out_ << "'shared_library',\n";
+ break;
+ case Target::SOURCE_SET:
+ out_ << "'static_library',\n"; // TODO(brettw) fixme.
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ if (target_->hard_dep())
+ out_ << " 'hard_dependency': 1,\n";
+}
+
+void GypBinaryTargetWriter::WriteFlags(const Target* target) {
+ WriteDefines(target);
+ WriteIncludes(target);
+ if (target->settings()->IsWin())
+ WriteVCFlags(target);
+}
+
+void GypBinaryTargetWriter::WriteDefines(const Target* target) {
+ out_ << " 'defines': [";
+ RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::defines,
+ StringWriter(), out_);
+ out_ << " ],\n";
+}
+
+void GypBinaryTargetWriter::WriteIncludes(const Target* target) {
+ out_ << " 'include_dirs': [";
+ RecursiveTargetConfigToStream<SourceDir>(target, &ConfigValues::include_dirs,
+ IncludeWriter(helper_), out_);
+ out_ << " ],\n";
+}
+
+void GypBinaryTargetWriter::WriteVCFlags(const Target* target) {
+ // C flags.
+ out_ << " 'msvs_settings': {\n";
+ out_ << " 'VCCLCompilerTool': {\n";
+
+ std::vector<std::string> cflags;
+ StringAccumulator acc(&cflags);
+ RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::cflags,
+ acc, out_);
+ // GYP always uses the VC optimization flag to add a /O? on Visual Studio.
+ // This can produce duplicate values. So look up the GYP value corresponding
+ // to the flags used, and set the same one.
+ std::string optimization = GetVCOptimization(&cflags);
+ WriteArray(out_, "AdditionalOptions", cflags, 14);
+ // TODO(brettw) cflags_c and cflags_cc!
+ out_ << " 'Optimization': " << optimization << ",\n";
+ out_ << " },\n";
+
+ // Linker tool stuff.
+ out_ << " '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': [";
+ for (size_t i = 0; i < all_lib_dirs.size(); i++) {
+ out_ << " '";
+ EscapeStringToStream(out_,
+ helper_.GetDirReference(all_lib_dirs[i], false),
+ escape_options);
+ out_ << "',";
+ }
+ out_ << " ],\n";
+ }
+
+ // ...Libraries.
+ const OrderedSet<std::string> all_libs = target->all_libs();
+ if (!all_libs.empty()) {
+ out_ << " 'AdditionalDependencies': [";
+ for (size_t i = 0; i < all_libs.size(); i++) {
+ out_ << " '";
+ EscapeStringToStream(out_, all_libs[i], escape_options);
+ out_ << "',";
+ }
+ out_ << " ],\n";
+ }
+
+ // ...LD flags.
+ // TODO(brettw) EnableUAC defaults to on and needs to be set. Also
+ // UACExecutionLevel and UACUIAccess depends on that and defaults to 0/false.
+ std::vector<std::string> ldflags;
+ acc.result = &ldflags;
+ RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::ldflags,
+ acc, out_);
+ WriteArray(out_, "AdditionalOptions", ldflags, 14);
+ out_ << " },\n";
+
+ out_ << " },\n";
+}
+
+void GypBinaryTargetWriter::WriteSources() {
+ out_ << " 'sources': [\n";
+
+ 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";
+ }
+
+ out_ << " ],\n";
+}
+
+void GypBinaryTargetWriter::WriteDeps() {
+ const std::vector<const Target*>& deps = target_->deps();
+ if (deps.empty())
+ return;
+
+ EscapeOptions escape_options;
+ escape_options.mode = ESCAPE_JSON;
+
+ out_ << " 'dependencies': [\n";
+ for (size_t i = 0; i < deps.size(); i++) {
+ out_ << " '";
+ EscapeStringToStream(out_, helper_.GetFullRefForTarget(deps[i]),
+ escape_options);
+ out_ << "',\n";
+ }
+ out_ << " ],\n";
+}

Powered by Google App Engine
This is Rietveld 408576698