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

Side by Side Diff: tools/gn/gyp_binary_target_writer.cc

Issue 132803008: Work on GN iOS GYP generation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/gyp_binary_target_writer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/gyp_binary_target_writer.h" 5 #include "tools/gn/gyp_binary_target_writer.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 // The arch was passed as one GN string value, e.g. "-arch i386". Return 86 // The arch was passed as one GN string value, e.g. "-arch i386". Return
87 // the stuff following the space and delete the item. 87 // the stuff following the space and delete the item.
88 std::string ret = cur.substr(6); 88 std::string ret = cur.substr(6);
89 cflags->erase(cflags->begin() + i); 89 cflags->erase(cflags->begin() + i);
90 return ret; 90 return ret;
91 } 91 }
92 } 92 }
93 return std::string(); 93 return std::string();
94 } 94 }
95 95
96 // Searches for -miphoneos-version-min, returns the resulting value, and
97 // removes it from the list. Returns the empty string if it's not found.
98 std::string GetIPhoneVersionMin(std::vector<std::string>* cflags) {
99 // Searches for the "-arch" option and returns the corresponding GYP value.
100 const char prefix[] = "-miphoneos-version-min=";
101 for (size_t i = 0; i < cflags->size(); i++) {
102 const std::string& cur = (*cflags)[i];
103 if (StartsWithASCII(cur, prefix, true)) {
104 std::string result = cur.substr(arraysize(prefix) - 1);
105 cflags->erase(cflags->begin() + i);
106 return result;
107 }
108 }
109 return std::string();
110 }
111
96 // Finds all values from the given getter from all configs in the given list, 112 // Finds all values from the given getter from all configs in the given list,
97 // and adds them to the given result vector. 113 // and adds them to the given result vector.
98 template<typename T> 114 template<typename T>
99 void FillConfigListValues( 115 void FillConfigListValues(
100 const LabelConfigVector& configs, 116 const LabelConfigVector& configs,
101 const std::vector<T>& (ConfigValues::* getter)() const, 117 const std::vector<T>& (ConfigValues::* getter)() const,
102 std::vector<T>* result) { 118 std::vector<T>* result) {
103 for (size_t config_i = 0; config_i < configs.size(); config_i++) { 119 for (size_t config_i = 0; config_i < configs.size(); config_i++) {
104 const std::vector<T>& values = 120 const std::vector<T>& values =
105 (configs[config_i].ptr->config_values().*getter)(); 121 (configs[config_i].ptr->config_values().*getter)();
106 for (size_t val_i = 0; val_i < values.size(); val_i++) 122 for (size_t val_i = 0; val_i < values.size(); val_i++)
107 result->push_back(values[val_i]); 123 result->push_back(values[val_i]);
108 } 124 }
109 } 125 }
110 126
127 bool IsClang(const Target* target) {
128 const Value* is_clang =
129 target->settings()->base_config()->GetValue("is_clang");
130 return is_clang && is_clang->type() == Value::BOOLEAN &&
131 is_clang->boolean_value();
132 }
133
134 bool IsIOS(const Target* target) {
135 const Value* is_ios = target->settings()->base_config()->GetValue("is_ios");
136 return is_ios && is_ios->type() == Value::BOOLEAN && is_ios->boolean_value();
137 }
138
139 // Returns true if the current target is an iOS simulator build.
140 bool IsIOSSimulator(const std::vector<std::string>& cflags) {
141 // Search for the sysroot flag. We expect one flag to be the
142 // switch, and the following one to be the value.
Nico 2014/02/05 04:19:35 I think both -isysroot foo and -isysroot=foo might
143 const char sysroot[] = "-isysroot";
144 for (size_t i = 0; i < cflags.size(); i++) {
145 const std::string& cur = cflags[i];
146 if (cur == sysroot) {
147 if (i == cflags.size() - 1)
148 return false; // No following value.
149
150 // The argument is a file path, we check the prefix of the file name.
151 base::FilePath path(UTF8ToFilePath(cflags[i + 1]));
152 std::string path_file_part = FilePathToUTF8(path.BaseName());
153 return StartsWithASCII(path_file_part, "iphonesimulator", false);
154 }
155 }
156 return false;
157 }
158
111 } // namespace 159 } // namespace
112 160
113 GypBinaryTargetWriter::Flags::Flags() {} 161 GypBinaryTargetWriter::Flags::Flags() {}
114 GypBinaryTargetWriter::Flags::~Flags() {} 162 GypBinaryTargetWriter::Flags::~Flags() {}
115 163
116 GypBinaryTargetWriter::GypBinaryTargetWriter(const TargetGroup& group, 164 GypBinaryTargetWriter::GypBinaryTargetWriter(const TargetGroup& group,
117 const Toolchain* debug_toolchain, 165 const Toolchain* debug_toolchain,
118 const SourceDir& gyp_dir, 166 const SourceDir& gyp_dir,
119 std::ostream& out) 167 std::ostream& out)
120 : GypTargetWriter(group.get()->item()->AsTarget(), debug_toolchain, 168 : GypTargetWriter(group.get()->item()->AsTarget(), debug_toolchain,
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 indent + kExtraIndent * 2); 423 indent + kExtraIndent * 2);
376 424
377 // ...LD flags. 425 // ...LD flags.
378 // TODO(brettw) EnableUAC defaults to on and needs to be set. Also 426 // TODO(brettw) EnableUAC defaults to on and needs to be set. Also
379 // UACExecutionLevel and UACUIAccess depends on that and defaults to 0/false. 427 // UACExecutionLevel and UACUIAccess depends on that and defaults to 0/false.
380 WriteNamedArray("AdditionalOptions", flags.ldflags, 14); 428 WriteNamedArray("AdditionalOptions", flags.ldflags, 14);
381 Indent(indent + kExtraIndent) << "},\n"; 429 Indent(indent + kExtraIndent) << "},\n";
382 Indent(indent) << "},\n"; 430 Indent(indent) << "},\n";
383 } 431 }
384 432
385 void GypBinaryTargetWriter::WriteMacFlags(Flags& flags, int indent) { 433 void GypBinaryTargetWriter::WriteMacFlags(const Target* target,
434 Flags& flags,
435 int indent) {
386 WriteNamedArray("defines", flags.defines, indent); 436 WriteNamedArray("defines", flags.defines, indent);
387 WriteIncludeDirs(flags, indent); 437 WriteIncludeDirs(flags, indent);
388 438
389 // Libraries and library directories. 439 // Libraries and library directories.
390 EscapeOptions escape_options; 440 EscapeOptions escape_options;
391 escape_options.mode = ESCAPE_JSON; 441 escape_options.mode = ESCAPE_JSON;
392 if (!flags.lib_dirs.empty()) { 442 if (!flags.lib_dirs.empty()) {
393 Indent(indent + kExtraIndent) << "'library_dirs': ["; 443 Indent(indent + kExtraIndent) << "'library_dirs': [";
394 for (size_t i = 0; i < flags.lib_dirs.size(); i++) { 444 for (size_t i = 0; i < flags.lib_dirs.size(); i++) {
395 out_ << " '"; 445 out_ << " '";
(...skipping 11 matching lines...) Expand all
407 out_ << " '-l"; 457 out_ << " '-l";
408 EscapeStringToStream(out_, flags.libs[i], escape_options); 458 EscapeStringToStream(out_, flags.libs[i], escape_options);
409 out_ << "',"; 459 out_ << "',";
410 } 460 }
411 out_ << " ],\n"; 461 out_ << " ],\n";
412 Indent(indent) << "},\n"; 462 Indent(indent) << "},\n";
413 } 463 }
414 464
415 Indent(indent) << "'xcode_settings': {\n"; 465 Indent(indent) << "'xcode_settings': {\n";
416 466
417 // Architecture. GYP uses this to write the -arch flag passed to the 467 // Architecture. GYP reads this value and uses it to generate the -arch
418 // compiler, it doesn't look at our -arch flag. So we need to specify it in 468 // flag, so we always want to remove it from the cflags (which is a side
419 // this special var and not in the cflags to avoid duplicates or conflicts. 469 // effect of what GetMacArch does), even in cases where we don't use the
470 // value (in the iOS arm below).
420 std::string arch = GetMacArch(&flags.cflags); 471 std::string arch = GetMacArch(&flags.cflags);
421 if (arch == "i386") 472 if (IsIOS(target)) {
422 Indent(indent + kExtraIndent) << "'ARCHS': [ 'i386' ],\n"; 473 // When writing an iOS "target" (not host) target, we set VALID_ARCHS
423 else if (arch == "x86_64") 474 // instead of ARCHS and always use this hardcoded value. This matches the
424 Indent(indent + kExtraIndent) << "'ARCHS': [ 'x86_64' ],\n"; 475 // GYP build.
476 Indent(indent + kExtraIndent) << "'VALID_ARCHS': 'armv7 i386',\n";
477
478 // Tell XCode to target both iPhone and iPad. GN has no such concept.
479 Indent(indent + kExtraIndent) << "'TARGETED_DEVICE_FAMILY': '1,2',\n";
Nico 2014/02/05 04:19:35 Hm, hardcoding this stuff in the gn binary seems s
brettw 2014/02/05 04:29:30 Yeah. Is there a command line option this maps to?
Nico 2014/02/05 04:55:27 I think this is written into the UIDeviceFamily pl
480
481 if (IsIOSSimulator(flags.cflags)) {
482 Indent(indent + kExtraIndent) << "'SDKROOT': 'iphonesimulator',\n";
483 } else {
484 Indent(indent + kExtraIndent) << "'SDKROOT': 'iphoneos',\n";
485 std::string min_ver = GetIPhoneVersionMin(&flags.cflags);
486 if (!min_ver.empty())
487 Indent(indent + kExtraIndent) << "'IPHONEOS_DEPLOYMENT_TARGET': '',\n";
488 }
489 } else {
490 // When doing regular Mac and "host" iOS (which look like regular Mac)
491 // builds, we can set the ARCHS value to what's specified in the build.
492 if (arch == "i386")
493 Indent(indent + kExtraIndent) << "'ARCHS': [ 'i386' ],\n";
494 else if (arch == "x86_64")
495 Indent(indent + kExtraIndent) << "'ARCHS': [ 'x86_64' ],\n";
Nico 2014/02/05 04:19:36 remoting sets ARCHS to both i386, x86_64 I think (
brettw 2014/02/05 04:29:30 Okay, we'll have to deal with that when it comes u
Nico 2014/02/05 04:55:27 The commit message on how this is done in gyp/ninj
brettw 2014/02/05 06:18:53 I *think* the way to do this in GN would be to jus
496 }
425 497
426 // C/C++ flags. 498 // C/C++ flags.
427 if (!flags.cflags.empty() || !flags.cflags_c.empty() || 499 if (!flags.cflags.empty() || !flags.cflags_c.empty() ||
428 !flags.cflags_objc.empty()) { 500 !flags.cflags_objc.empty()) {
429 Indent(indent + kExtraIndent) << "'OTHER_CFLAGS': ["; 501 Indent(indent + kExtraIndent) << "'OTHER_CFLAGS': [";
430 WriteArrayValues(out_, flags.cflags); 502 WriteArrayValues(out_, flags.cflags);
431 WriteArrayValues(out_, flags.cflags_c); 503 WriteArrayValues(out_, flags.cflags_c);
432 WriteArrayValues(out_, flags.cflags_objc); 504 WriteArrayValues(out_, flags.cflags_objc);
433 out_ << " ],\n"; 505 out_ << " ],\n";
434 } 506 }
435 if (!flags.cflags.empty() || !flags.cflags_cc.empty() || 507 if (!flags.cflags.empty() || !flags.cflags_cc.empty() ||
436 !flags.cflags_objcc.empty()) { 508 !flags.cflags_objcc.empty()) {
437 Indent(indent + kExtraIndent) << "'OTHER_CPLUSPLUSFLAGS': ["; 509 Indent(indent + kExtraIndent) << "'OTHER_CPLUSPLUSFLAGS': [";
438 WriteArrayValues(out_, flags.cflags); 510 WriteArrayValues(out_, flags.cflags);
439 WriteArrayValues(out_, flags.cflags_cc); 511 WriteArrayValues(out_, flags.cflags_cc);
440 WriteArrayValues(out_, flags.cflags_objcc); 512 WriteArrayValues(out_, flags.cflags_objcc);
441 out_ << " ],\n"; 513 out_ << " ],\n";
442 } 514 }
443 515
444 // Ld flags. Don't write these for static libraries. Otherwise, they'll be 516 // Ld flags. Don't write these for static libraries. Otherwise, they'll be
445 // passed to the library tool which doesn't expect it (the toolchain does 517 // passed to the library tool which doesn't expect it (the toolchain does
446 // not use ldflags so these are ignored in the normal build). 518 // not use ldflags so these are ignored in the normal build).
447 if (target_->output_type() != Target::STATIC_LIBRARY) 519 if (target->output_type() != Target::STATIC_LIBRARY)
448 WriteNamedArray("OTHER_LDFLAGS", flags.ldflags, indent + kExtraIndent); 520 WriteNamedArray("OTHER_LDFLAGS", flags.ldflags, indent + kExtraIndent);
449 521
450 // Write the compiler that XCode should use. When we're using clang, we want 522 // Write the compiler that XCode should use. When we're using clang, we want
451 // the custom one, otherwise don't add this and the default compiler will be 523 // the custom one, otherwise don't add this and the default compiler will be
452 // used. 524 // used.
453 // 525 //
454 // TODO(brettw) this is a hack. We could add a way for the GN build to set 526 // TODO(brettw) this is a hack. We could add a way for the GN build to set
455 // these values but as far as I can see this is the only use for them, so 527 // these values but as far as I can see this is the only use for them, so
456 // currently we manually check the build config's is_clang value. 528 // currently we manually check the build config's is_clang value.
457 const Value* is_clang = 529 if (IsClang(target)) {
458 target_->settings()->base_config()->GetValue("is_clang");
459 if (is_clang && is_clang->type() == Value::BOOLEAN &&
460 is_clang->boolean_value()) {
461 base::FilePath clang_path = 530 base::FilePath clang_path =
462 target_->settings()->build_settings()->GetFullPath(SourceFile( 531 target_->settings()->build_settings()->GetFullPath(SourceFile(
463 "//third_party/llvm-build/Release+Asserts/bin/clang")); 532 "//third_party/llvm-build/Release+Asserts/bin/clang"));
464 base::FilePath clang_pp_path = 533 base::FilePath clang_pp_path =
465 target_->settings()->build_settings()->GetFullPath(SourceFile( 534 target_->settings()->build_settings()->GetFullPath(SourceFile(
466 "//third_party/llvm-build/Release+Asserts/bin/clang++")); 535 "//third_party/llvm-build/Release+Asserts/bin/clang++"));
467 536
468 Indent(indent + kExtraIndent) 537 Indent(indent + kExtraIndent)
469 << "'CC': '" << FilePathToUTF8(clang_path) << "',\n"; 538 << "'CC': '" << FilePathToUTF8(clang_path) << "',\n";
470 Indent(indent + kExtraIndent) 539 Indent(indent + kExtraIndent)
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 if (host) { 595 if (host) {
527 // Write out the first part of the conditional. 596 // Write out the first part of the conditional.
528 Indent(indent) << kToolsetTargetCondition; 597 Indent(indent) << kToolsetTargetCondition;
529 extra_indent = kExtraIndent; 598 extra_indent = kExtraIndent;
530 } 599 }
531 600
532 // Always write the target flags (may or may not be inside a target 601 // Always write the target flags (may or may not be inside a target
533 // conditional). 602 // conditional).
534 { 603 {
535 Flags flags(FlagsFromTarget(target->item()->AsTarget())); 604 Flags flags(FlagsFromTarget(target->item()->AsTarget()));
536 WriteMacFlags(flags, indent + extra_indent); 605 WriteMacFlags(target->item()->AsTarget(), flags, indent + extra_indent);
537 } 606 }
538 607
539 // Now optionally write the host conditional arm. 608 // Now optionally write the host conditional arm.
540 if (host) { 609 if (host) {
541 Indent(indent) << kToolsetTargetElse; 610 Indent(indent) << kToolsetTargetElse;
542 Flags flags(FlagsFromTarget(host->item()->AsTarget())); 611 Flags flags(FlagsFromTarget(host->item()->AsTarget()));
543 WriteMacFlags(flags, indent + kExtraIndent); 612 WriteMacFlags(host->item()->AsTarget(), flags, indent + kExtraIndent);
544 Indent(indent) << kToolsetTargetEnd; 613 Indent(indent) << kToolsetTargetEnd;
545 } 614 }
546 } 615 }
547 616
548 void GypBinaryTargetWriter::WriteSources(const Target* target, int indent) { 617 void GypBinaryTargetWriter::WriteSources(const Target* target, int indent) {
549 Indent(indent) << "'sources': [\n"; 618 Indent(indent) << "'sources': [\n";
550 619
551 const Target::FileList& sources = target->sources(); 620 const Target::FileList& sources = target->sources();
552 for (size_t i = 0; i < sources.size(); i++) { 621 for (size_t i = 0; i < sources.size(); i++) {
553 const SourceFile& input_file = sources[i]; 622 const SourceFile& input_file = sources[i];
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 if (target_->direct_dependent_configs().empty()) 667 if (target_->direct_dependent_configs().empty())
599 return; 668 return;
600 Indent(indent) << "'direct_dependent_settings': {\n"; 669 Indent(indent) << "'direct_dependent_settings': {\n";
601 670
602 Flags flags(FlagsFromConfigList(target_->direct_dependent_configs())); 671 Flags flags(FlagsFromConfigList(target_->direct_dependent_configs()));
603 if (target_->settings()->IsLinux()) 672 if (target_->settings()->IsLinux())
604 WriteLinuxFlags(flags, indent + kExtraIndent); 673 WriteLinuxFlags(flags, indent + kExtraIndent);
605 else if (target_->settings()->IsWin()) 674 else if (target_->settings()->IsWin())
606 WriteVCFlags(flags, indent + kExtraIndent); 675 WriteVCFlags(flags, indent + kExtraIndent);
607 else if (target_->settings()->IsMac()) 676 else if (target_->settings()->IsMac())
608 WriteMacFlags(flags, indent + kExtraIndent); 677 WriteMacFlags(target_, flags, indent + kExtraIndent);
609 Indent(indent) << "},\n"; 678 Indent(indent) << "},\n";
610 } 679 }
611 680
612 void GypBinaryTargetWriter::WriteAllDependentSettings(int indent) { 681 void GypBinaryTargetWriter::WriteAllDependentSettings(int indent) {
613 if (target_->all_dependent_configs().empty()) 682 if (target_->all_dependent_configs().empty())
614 return; 683 return;
615 Indent(indent) << "'all_dependent_settings': {\n"; 684 Indent(indent) << "'all_dependent_settings': {\n";
616 685
617 Flags flags(FlagsFromConfigList(target_->all_dependent_configs())); 686 Flags flags(FlagsFromConfigList(target_->all_dependent_configs()));
618 if (target_->settings()->IsLinux()) 687 if (target_->settings()->IsLinux())
619 WriteLinuxFlags(flags, indent + kExtraIndent); 688 WriteLinuxFlags(flags, indent + kExtraIndent);
620 else if (target_->settings()->IsWin()) 689 else if (target_->settings()->IsWin())
621 WriteVCFlags(flags, indent + kExtraIndent); 690 WriteVCFlags(flags, indent + kExtraIndent);
622 else if (target_->settings()->IsMac()) 691 else if (target_->settings()->IsMac())
623 WriteMacFlags(flags, indent + kExtraIndent); 692 WriteMacFlags(target_, flags, indent + kExtraIndent);
624 Indent(indent) << "},\n"; 693 Indent(indent) << "},\n";
625 } 694 }
626 695
627 GypBinaryTargetWriter::Flags GypBinaryTargetWriter::FlagsFromTarget( 696 GypBinaryTargetWriter::Flags GypBinaryTargetWriter::FlagsFromTarget(
628 const Target* target) const { 697 const Target* target) const {
629 Flags ret; 698 Flags ret;
630 699
631 // Extracts a vector of the given type and name from the config values. 700 // Extracts a vector of the given type and name from the config values.
632 #define EXTRACT(type, name) \ 701 #define EXTRACT(type, name) \
633 { \ 702 { \
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 return; 758 return;
690 759
691 EscapeOptions options; 760 EscapeOptions options;
692 options.mode = ESCAPE_JSON; 761 options.mode = ESCAPE_JSON;
693 762
694 Indent(indent) << "'" << name << "': ["; 763 Indent(indent) << "'" << name << "': [";
695 WriteArrayValues(out_, values); 764 WriteArrayValues(out_, values);
696 out_ << " ],\n"; 765 out_ << " ],\n";
697 } 766 }
698 767
OLDNEW
« no previous file with comments | « tools/gn/gyp_binary_target_writer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698