Work on GYP generation for GN. The hybrid build now works in xcode and ninja. Write mac tool to output dir in toolchain setup. BUG= R=thakis@chromium.org Review URL: https://codereview.chromium.org/46683002 Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 42b80efc8d8588bf369f428129333c7447070ebd
diff --git a/tools/gn/args.cc b/tools/gn/args.cc index 2eead42..2d9aa6e 100644 --- a/tools/gn/args.cc +++ b/tools/gn/args.cc
@@ -135,9 +135,12 @@ } // Only set on the current scope to the new value if it hasn't been already - // set. - if (!scope_to_set->GetValue(i->first)) + // set. Mark the variable used so the build script can override it in + // certain cases without getting unused value errors. + if (!scope_to_set->GetValue(i->first)) { scope_to_set->SetValue(i->first, i->second, i->second.origin()); + scope_to_set->MarkUsed(i->first); + } } return true;
diff --git a/tools/gn/command_gyp.cc b/tools/gn/command_gyp.cc index de089d3..3c6bef9 100644 --- a/tools/gn/command_gyp.cc +++ b/tools/gn/command_gyp.cc
@@ -233,9 +233,6 @@ for (CorrelatedTargetsMap::iterator i = correlated.begin(); i != correlated.end(); ++i) { const TargetGroup& group = i->second; - if (!EnsureTargetsMatch(group, err)) - return std::make_pair(0, 0); - if (!group.debug->item_node()->should_generate()) continue; // Skip non-generated ones. if (group.debug->external()) @@ -243,6 +240,9 @@ if (group.debug->gyp_file().is_null()) continue; // Skip ones without GYP files. + if (!EnsureTargetsMatch(group, err)) + return std::make_pair(0, 0); + target_count++; grouped_targets[helper.GetGypFileForTarget(group.debug, err)].push_back( group);
diff --git a/tools/gn/gyp_binary_target_writer.cc b/tools/gn/gyp_binary_target_writer.cc index 7c4e7a3..bcbe7ee 100644 --- a/tools/gn/gyp_binary_target_writer.cc +++ b/tools/gn/gyp_binary_target_writer.cc
@@ -10,6 +10,7 @@ #include "tools/gn/config_values_extractors.h" #include "tools/gn/err.h" #include "tools/gn/escape.h" +#include "tools/gn/filesystem_utils.h" #include "tools/gn/settings.h" #include "tools/gn/target.h" @@ -132,15 +133,12 @@ WriteName(indent + kExtraIndent); WriteType(indent + kExtraIndent); - if (target_->settings()->IsLinux()) { + if (target_->settings()->IsLinux()) WriteLinuxConfiguration(indent + kExtraIndent); - } else if (target_->settings()->IsWin()) { + else if (target_->settings()->IsWin()) WriteVCConfiguration(indent + kExtraIndent); - } else if (target_->settings()->IsMac()) { - // TODO(brettw) mac. - NOTREACHED(); - //WriteMacConfiguration(); - } + else if (target_->settings()->IsMac()) + WriteMacConfiguration(indent + kExtraIndent); WriteDirectDependentSettings(indent + kExtraIndent); WriteAllDependentSettings(indent + kExtraIndent); @@ -256,6 +254,25 @@ WriteDeps(target_, indent); } +void GypBinaryTargetWriter::WriteMacConfiguration(int indent) { + Indent(indent) << "'configurations': {\n"; + + Indent(indent + kExtraIndent) << "'Debug': {\n"; + Flags debug_flags(FlagsFromTarget(group_.debug)); + WriteMacFlags(debug_flags, indent + kExtraIndent * 2); + Indent(indent + kExtraIndent) << "},\n"; + + Indent(indent + kExtraIndent) << "'Release': {\n"; + Flags release_flags(FlagsFromTarget(group_.release)); + WriteMacFlags(release_flags, indent + kExtraIndent * 2); + Indent(indent + kExtraIndent) << "},\n"; + + Indent(indent) << "},\n"; + + WriteSources(target_, indent); + WriteDeps(target_, indent); +} + void GypBinaryTargetWriter::WriteVCFlags(Flags& flags, int indent) { // Defines and includes go outside of the msvs settings. WriteNamedArray(out_, "defines", flags.defines, indent); @@ -306,6 +323,78 @@ Indent(indent) << "},\n"; } +void GypBinaryTargetWriter::WriteMacFlags(Flags& flags, int indent) { + WriteNamedArray(out_, "defines", flags.defines, indent); + WriteIncludeDirs(flags, indent); + + // Libraries and library directories. + EscapeOptions escape_options; + escape_options.mode = ESCAPE_JSON; + if (!flags.lib_dirs.empty()) { + Indent(indent + kExtraIndent) << "'library_dirs': ["; + for (size_t i = 0; i < flags.lib_dirs.size(); i++) { + out_ << " '"; + EscapeStringToStream(out_, + helper_.GetDirReference(flags.lib_dirs[i], false), + escape_options); + out_ << "',"; + } + out_ << " ],\n"; + } + if (!flags.libs.empty()) { + Indent(indent) << "'link_settings': {\n"; + Indent(indent + kExtraIndent) << "'libraries': ["; + for (size_t i = 0; i < flags.libs.size(); i++) { + out_ << " '-l"; + EscapeStringToStream(out_, flags.libs[i], escape_options); + out_ << "',"; + } + out_ << " ],\n"; + Indent(indent) << "},\n"; + } + + Indent(indent) << "'xcode_settings': {\n"; + + // C/C++ flags. + if (!flags.cflags.empty() || !flags.cflags_c.empty() || + !flags.cflags_objc.empty()) { + Indent(indent + kExtraIndent) << "'OTHER_CFLAGS': ["; + WriteArrayValues(out_, flags.cflags); + WriteArrayValues(out_, flags.cflags_c); + WriteArrayValues(out_, flags.cflags_objc); + out_ << " ],\n"; + } + if (!flags.cflags.empty() || !flags.cflags_cc.empty() || + !flags.cflags_objcc.empty()) { + Indent(indent + kExtraIndent) << "'OTHER_CPLUSPLUSFLAGS': ["; + WriteArrayValues(out_, flags.cflags); + WriteArrayValues(out_, flags.cflags_cc); + WriteArrayValues(out_, flags.cflags_objcc); + out_ << " ],\n"; + } + + // Ld flags. Don't write these for static libraries. Otherwise, they'll be + // passed to the library tool which doesn't expect it (the toolchain does + // not use ldflags so these are ignored in the normal build). + if (target_->output_type() != Target::STATIC_LIBRARY) { + WriteNamedArray(out_, "OTHER_LDFLAGS", flags.ldflags, + indent + kExtraIndent); + } + + base::FilePath clang_path = + target_->settings()->build_settings()->GetFullPath(SourceFile( + "//third_party/llvm-build/Release+Asserts/bin/clang")); + base::FilePath clang_pp_path = + target_->settings()->build_settings()->GetFullPath(SourceFile( + "//third_party/llvm-build/Release+Asserts/bin/clang++")); + + Indent(indent) << "'CC': '" << FilePathToUTF8(clang_path) << "',\n"; + Indent(indent) << "'LDPLUSPLUS': '" + << FilePathToUTF8(clang_pp_path) << "',\n"; + + Indent(indent) << "},\n"; +} + void GypBinaryTargetWriter::WriteLinuxFlagsForTarget(const Target* target, int indent) { Flags flags(FlagsFromTarget(target)); @@ -398,14 +487,12 @@ out_ << "'direct_dependent_settings': {\n"; Flags flags(FlagsFromConfigList(target_->direct_dependent_configs())); - if (target_->settings()->IsLinux()) { + if (target_->settings()->IsLinux()) WriteLinuxFlags(flags, indent + kExtraIndent); - } else if (target_->settings()->IsWin()) { + else if (target_->settings()->IsWin()) WriteVCFlags(flags, indent + kExtraIndent); - } else if (target_->settings()->IsMac()) { - // TODO(brettw) write mac. - NOTREACHED(); - } + else if (target_->settings()->IsMac()) + WriteMacFlags(flags, indent + kExtraIndent); Indent(indent) << "},\n"; } @@ -415,14 +502,12 @@ Indent(indent) << "'all_dependent_settings': {\n"; Flags flags(FlagsFromConfigList(target_->all_dependent_configs())); - if (target_->settings()->IsLinux()) { + if (target_->settings()->IsLinux()) WriteLinuxFlags(flags, indent + kExtraIndent); - } else if (target_->settings()->IsWin()) { + else if (target_->settings()->IsWin()) WriteVCFlags(flags, indent + kExtraIndent); - } else if (target_->settings()->IsMac()) { - // TODO(brettw) write mac. - NOTREACHED(); - } + else if (target_->settings()->IsMac()) + WriteMacFlags(flags, indent + kExtraIndent); Indent(indent) << "},\n"; }
diff --git a/tools/gn/gyp_binary_target_writer.h b/tools/gn/gyp_binary_target_writer.h index b12f154..226ffb8 100644 --- a/tools/gn/gyp_binary_target_writer.h +++ b/tools/gn/gyp_binary_target_writer.h
@@ -48,11 +48,13 @@ // Writes the flags, sources, and deps. void WriteVCConfiguration(int indent); void WriteLinuxConfiguration(int indent); + void WriteMacConfiguration(int indent); - // Writes the Visual Studio flags, defines, etc. The flags input is non-const - // because the cflags will be fixed up to account for things converted to - // VC settings (rather than compiler flags). + // Writes the flags, defines, etc. The flags input is non-const because the + // cflags will be fixed up to account for things converted to VC settings + // (rather than compiler flags). void WriteVCFlags(Flags& flags, int indent); + void WriteMacFlags(Flags& flags, int indent); // Writes the Linux compiler and linker flags. The first version does the // flags for the given target, the second version takes a pregenerted list of
diff --git a/tools/gn/gyp_target_writer.cc b/tools/gn/gyp_target_writer.cc index 5f35054..8a55bdc 100644 --- a/tools/gn/gyp_target_writer.cc +++ b/tools/gn/gyp_target_writer.cc
@@ -37,6 +37,19 @@ file << "# Generated by GN. Do not edit.\n\n"; file << "{\n"; file << " 'skip_includes': 1,\n"; + + if (targets[0].debug->settings()->IsMac()) { + // Global settings for make/ninja. This must match common.gypi :( + file << " 'make_global_settings': [\n"; + file << " ['CC', 'third_party/llvm-build/Release+Asserts/bin/clang'],\n"; + file << + " ['CXX', 'third_party/llvm-build/Release+Asserts/bin/clang++'],\n"; + file << " ['CC.host', '$(CC)'],\n"; + file << " ['CXX.host', '$(CXX)'],\n"; + file << " ],\n"; + } + // TODO(brettw) android. + file << " 'targets': [\n"; for (size_t i = 0; i < targets.size(); i++) {
diff --git a/tools/gn/secondary/build/config/BUILDCONFIG.gn b/tools/gn/secondary/build/config/BUILDCONFIG.gn index 78a3f27..99e1e91 100644 --- a/tools/gn/secondary/build/config/BUILDCONFIG.gn +++ b/tools/gn/secondary/build/config/BUILDCONFIG.gn
@@ -79,6 +79,7 @@ is_nacl = false is_posix = true is_win = false + is_clang = true # Always use clang on Mac. } else if (os == "android") { is_android = false is_chromeos = false
diff --git a/tools/gn/secondary/build/config/compiler/BUILD.gn b/tools/gn/secondary/build/config/compiler/BUILD.gn index 6174b2e..ef9d61f 100644 --- a/tools/gn/secondary/build/config/compiler/BUILD.gn +++ b/tools/gn/secondary/build/config/compiler/BUILD.gn
@@ -116,9 +116,7 @@ # Clang-specific compiler flags setup. # ------------------------------------ - # TODO(brettw) these should be clang-only. For now, make it mac-only since - # that's where we always use clang. - if (is_mac) { # if (is_clang) { + if (is_clang) { cflags += [ "-fcolor-diagnostics", ] @@ -301,7 +299,7 @@ # TODO(brettw) Ones below here should be clang-only when we have a flag # for it. - if (is_mac) { #if (is_clang) { + if (is_clang) { cflags += [ "-Wheader-hygiene",
diff --git a/tools/gn/secondary/build/toolchain/mac/BUILD.gn b/tools/gn/secondary/build/toolchain/mac/BUILD.gn index 2752d5a..b8a3c5e 100644 --- a/tools/gn/secondary/build/toolchain/mac/BUILD.gn +++ b/tools/gn/secondary/build/toolchain/mac/BUILD.gn
@@ -2,10 +2,19 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# Should only be running on Mac. +assert(is_mac) + cc = rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang", ".", root_build_dir) cxx = rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang++", ".", root_build_dir) ld = cxx +# This will copy the gyp-mac-tool to the build directory. We pass in the source +# file of the win tool. +gyp_mac_tool_source = + rebase_path("//tools/gyp/pylib/gyp/mac_tool.py", ".", root_build_dir) +exec_script("setup_toolchain.py", [ gyp_mac_tool_source ], "value") + toolchain("clang") { # Make these apply to all tools below. lib_prefix = "-l"
diff --git a/tools/gn/secondary/build/toolchain/mac/setup_toolchain.py b/tools/gn/secondary/build/toolchain/mac/setup_toolchain.py new file mode 100644 index 0000000..431078f --- /dev/null +++ b/tools/gn/secondary/build/toolchain/mac/setup_toolchain.py
@@ -0,0 +1,29 @@ +# 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. + +import os +import stat +import sys + +def CopyTool(source_path): + """Copies the given tool to the current directory, including a warning not + to edit it.""" + with open(source_path) as source_file: + tool_source = source_file.readlines() + + # Add header and write it out to the current directory (which should be the + # root build dir). + out_path = 'gyp-mac-tool' + with open(out_path, 'w') as tool_file: + tool_file.write(''.join([tool_source[0], + '# Generated by setup_toolchain.py do not edit.\n'] + + tool_source[1:])) + st = os.stat(out_path) + os.chmod(out_path, st.st_mode | stat.S_IEXEC) + +# Find the tool source, it's the first argument, and copy it. +if len(sys.argv) != 2: + print "Need one argument (mac_tool source path)." + sys.exit(1) +CopyTool(sys.argv[1])