| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/xcode_object.h" | 5 #include "tools/gn/xcode_object.h" |
| 6 | 6 |
| 7 #include <iomanip> | 7 #include <iomanip> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 out << pair.first << " = "; | 215 out << pair.first << " = "; |
| 216 PrintValue(out, sub_rule, pair.second); | 216 PrintValue(out, sub_rule, pair.second); |
| 217 out << ";" << (rules.one_line ? " " : "\n"); | 217 out << ";" << (rules.one_line ? " " : "\n"); |
| 218 } | 218 } |
| 219 | 219 |
| 220 if (!rules.one_line && rules.level) | 220 if (!rules.one_line && rules.level) |
| 221 out << std::string(rules.level, '\t'); | 221 out << std::string(rules.level, '\t'); |
| 222 out << "}"; | 222 out << "}"; |
| 223 } | 223 } |
| 224 | 224 |
| 225 // Single entry values will by printed as value, multiple entries as vector |
| 226 template <typename ValueType> |
| 227 void PrintValue(std::ostream& out, |
| 228 IndentRules rules, |
| 229 const std::multimap<std::string, ValueType>& values) { |
| 230 IndentRules sub_rule{rules.one_line, rules.level + 1}; |
| 231 out << "{" << (rules.one_line ? " " : "\n"); |
| 232 |
| 233 for (auto i = values.begin(); i != values.end();) { |
| 234 if (!sub_rule.one_line) |
| 235 out << std::string(sub_rule.level, '\t'); |
| 236 out << i->first << " = "; |
| 237 auto upper = values.upper_bound(i->first); |
| 238 std::vector<ValueType> values; |
| 239 while (i != upper) { |
| 240 values.push_back(i->second); |
| 241 ++i; |
| 242 } |
| 243 if (values.size() == 1) { |
| 244 PrintValue(out, sub_rule, values.front()); |
| 245 } else { |
| 246 PrintValue(out, sub_rule, values); |
| 247 } |
| 248 |
| 249 out << ";" << (rules.one_line ? " " : "\n"); |
| 250 } |
| 251 |
| 252 if (!rules.one_line && rules.level) |
| 253 out << std::string(rules.level, '\t'); |
| 254 out << "}"; |
| 255 } |
| 256 |
| 225 template <typename ValueType> | 257 template <typename ValueType> |
| 226 void PrintProperty(std::ostream& out, | 258 void PrintProperty(std::ostream& out, |
| 227 IndentRules rules, | 259 IndentRules rules, |
| 228 const char* name, | 260 const char* name, |
| 229 ValueType&& value) { | 261 ValueType&& value) { |
| 230 if (!rules.one_line && rules.level) | 262 if (!rules.one_line && rules.level) |
| 231 out << std::string(rules.level, '\t'); | 263 out << std::string(rules.level, '\t'); |
| 232 | 264 |
| 233 out << name << " = "; | 265 out << name << " = "; |
| 234 PrintValue(out, rules, std::forward<ValueType>(value)); | 266 PrintValue(out, rules, std::forward<ValueType>(value)); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 PrintProperty(out, rules, "buildPhases", build_phases_); | 390 PrintProperty(out, rules, "buildPhases", build_phases_); |
| 359 PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector()); | 391 PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector()); |
| 360 PrintProperty(out, rules, "name", name_); | 392 PrintProperty(out, rules, "name", name_); |
| 361 PrintProperty(out, rules, "productName", name_); | 393 PrintProperty(out, rules, "productName", name_); |
| 362 out << indent_str << "};\n"; | 394 out << indent_str << "};\n"; |
| 363 } | 395 } |
| 364 | 396 |
| 365 // PBXBuildFile --------------------------------------------------------------- | 397 // PBXBuildFile --------------------------------------------------------------- |
| 366 | 398 |
| 367 PBXBuildFile::PBXBuildFile(const PBXFileReference* file_reference, | 399 PBXBuildFile::PBXBuildFile(const PBXFileReference* file_reference, |
| 368 const PBXSourcesBuildPhase* build_phase) | 400 const PBXSourcesBuildPhase* build_phase, |
| 369 : file_reference_(file_reference), build_phase_(build_phase) { | 401 const std::string& cflags) |
| 402 : file_reference_(file_reference), |
| 403 build_phase_(build_phase), |
| 404 cflags_(cflags) { |
| 370 DCHECK(file_reference_); | 405 DCHECK(file_reference_); |
| 371 DCHECK(build_phase_); | 406 DCHECK(build_phase_); |
| 372 } | 407 } |
| 373 | 408 |
| 374 PBXBuildFile::~PBXBuildFile() {} | 409 PBXBuildFile::~PBXBuildFile() {} |
| 375 | 410 |
| 376 PBXObjectClass PBXBuildFile::Class() const { | 411 PBXObjectClass PBXBuildFile::Class() const { |
| 377 return PBXBuildFileClass; | 412 return PBXBuildFileClass; |
| 378 } | 413 } |
| 379 | 414 |
| 380 std::string PBXBuildFile::Name() const { | 415 std::string PBXBuildFile::Name() const { |
| 381 return file_reference_->Name() + " in " + build_phase_->Name(); | 416 return file_reference_->Name() + " in " + build_phase_->Name(); |
| 382 } | 417 } |
| 383 | 418 |
| 384 void PBXBuildFile::Print(std::ostream& out, unsigned indent) const { | 419 void PBXBuildFile::Print(std::ostream& out, unsigned indent) const { |
| 385 const std::string indent_str(indent, '\t'); | 420 const std::string indent_str(indent, '\t'); |
| 386 const IndentRules rules = {true, 0}; | 421 const IndentRules rules = {true, 0}; |
| 387 out << indent_str << Reference() << " = {"; | 422 out << indent_str << Reference() << " = {"; |
| 388 PrintProperty(out, rules, "isa", ToString(Class())); | 423 PrintProperty(out, rules, "isa", ToString(Class())); |
| 389 PrintProperty(out, rules, "fileRef", file_reference_); | 424 PrintProperty(out, rules, "fileRef", file_reference_); |
| 425 if (!cflags_.empty()) { |
| 426 std::map<std::string, std::string> settings; |
| 427 settings["COMPILER_FLAGS"] = cflags_; |
| 428 PrintProperty(out, rules, "settings", settings); |
| 429 } |
| 390 out << "};\n"; | 430 out << "};\n"; |
| 391 } | 431 } |
| 392 | 432 |
| 393 // PBXFileReference ----------------------------------------------------------- | 433 // PBXFileReference ----------------------------------------------------------- |
| 394 | 434 |
| 395 PBXFileReference::PBXFileReference(const std::string& name, | 435 PBXFileReference::PBXFileReference(const std::string& name, |
| 396 const std::string& path, | 436 const std::string& path, |
| 397 const std::string& type) | 437 const std::string& type) |
| 398 : name_(name), path_(path), type_(type) {} | 438 : name_(name), path_(path), type_(type) {} |
| 399 | 439 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 DCHECK(product_reference_); | 592 DCHECK(product_reference_); |
| 553 build_phases_.push_back(base::WrapUnique(new PBXSourcesBuildPhase)); | 593 build_phases_.push_back(base::WrapUnique(new PBXSourcesBuildPhase)); |
| 554 source_build_phase_ = | 594 source_build_phase_ = |
| 555 static_cast<PBXSourcesBuildPhase*>(build_phases_.back().get()); | 595 static_cast<PBXSourcesBuildPhase*>(build_phases_.back().get()); |
| 556 | 596 |
| 557 build_phases_.push_back(base::WrapUnique(new PBXFrameworksBuildPhase)); | 597 build_phases_.push_back(base::WrapUnique(new PBXFrameworksBuildPhase)); |
| 558 } | 598 } |
| 559 | 599 |
| 560 PBXNativeTarget::~PBXNativeTarget() {} | 600 PBXNativeTarget::~PBXNativeTarget() {} |
| 561 | 601 |
| 562 void PBXNativeTarget::AddFileForIndexing( | 602 void PBXNativeTarget::AddFileForIndexing(const PBXFileReference* file_reference, |
| 563 const PBXFileReference* file_reference) { | 603 const std::string& cflags) { |
| 564 DCHECK(file_reference); | 604 DCHECK(file_reference); |
| 565 source_build_phase_->AddBuildFile( | 605 source_build_phase_->AddBuildFile(base::WrapUnique( |
| 566 base::WrapUnique(new PBXBuildFile(file_reference, source_build_phase_))); | 606 new PBXBuildFile(file_reference, source_build_phase_, cflags))); |
| 567 } | 607 } |
| 568 | 608 |
| 569 PBXObjectClass PBXNativeTarget::Class() const { | 609 PBXObjectClass PBXNativeTarget::Class() const { |
| 570 return PBXNativeTargetClass; | 610 return PBXNativeTargetClass; |
| 571 } | 611 } |
| 572 | 612 |
| 573 void PBXNativeTarget::Print(std::ostream& out, unsigned indent) const { | 613 void PBXNativeTarget::Print(std::ostream& out, unsigned indent) const { |
| 574 const std::string indent_str(indent, '\t'); | 614 const std::string indent_str(indent, '\t'); |
| 575 const IndentRules rules = {false, indent + 1}; | 615 const IndentRules rules = {false, indent + 1}; |
| 576 out << indent_str << Reference() << " = {\n"; | 616 out << indent_str << Reference() << " = {\n"; |
| 577 PrintProperty(out, rules, "isa", ToString(Class())); | 617 PrintProperty(out, rules, "isa", ToString(Class())); |
| 578 PrintProperty(out, rules, "buildConfigurationList", configurations_); | 618 PrintProperty(out, rules, "buildConfigurationList", configurations_); |
| 579 PrintProperty(out, rules, "buildPhases", build_phases_); | 619 PrintProperty(out, rules, "buildPhases", build_phases_); |
| 580 PrintProperty(out, rules, "buildRules", EmptyPBXObjectVector()); | 620 PrintProperty(out, rules, "buildRules", EmptyPBXObjectVector()); |
| 581 PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector()); | 621 PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector()); |
| 582 PrintProperty(out, rules, "name", name_); | 622 PrintProperty(out, rules, "name", name_); |
| 583 PrintProperty(out, rules, "productName", product_name_); | 623 PrintProperty(out, rules, "productName", product_name_); |
| 584 PrintProperty(out, rules, "productReference", product_reference_); | 624 PrintProperty(out, rules, "productReference", product_reference_); |
| 585 PrintProperty(out, rules, "productType", product_type_); | 625 PrintProperty(out, rules, "productType", product_type_); |
| 586 out << indent_str << "};\n"; | 626 out << indent_str << "};\n"; |
| 587 } | 627 } |
| 588 | 628 |
| 589 // PBXProject ----------------------------------------------------------------- | 629 // PBXProject ----------------------------------------------------------------- |
| 590 | 630 |
| 591 PBXProject::PBXProject(const std::string& name, | 631 PBXProject::PBXProject(const std::string& name, |
| 592 const std::string& config_name, | 632 const std::string& config_name, |
| 593 const std::string& source_path, | 633 const std::string& source_path, |
| 594 const PBXAttributes& attributes) | 634 const PBXAttributes& attributes) |
| 595 : name_(name), config_name_(config_name), target_for_indexing_(nullptr) { | 635 : name_(name), config_name_(config_name), target_for_indexing_(nullptr) { |
| 596 attributes_["BuildIndependentTargetsInParallel"] = "YES"; | 636 if (attributes_.find("BuildIndependentTargetsInParallel") == |
| 637 attributes_.end()) |
| 638 attributes_.insert( |
| 639 std::make_pair("BuildIndependentTargetsInParallel", "YES")); |
| 597 | 640 |
| 598 main_group_.reset(new PBXGroup); | 641 main_group_.reset(new PBXGroup); |
| 599 sources_ = static_cast<PBXGroup*>(main_group_->AddChild( | 642 sources_ = static_cast<PBXGroup*>(main_group_->AddChild( |
| 600 base::WrapUnique(new PBXGroup(source_path, "Source")))); | 643 base::WrapUnique(new PBXGroup(source_path, "Source")))); |
| 601 products_ = static_cast<PBXGroup*>(main_group_->AddChild( | 644 products_ = static_cast<PBXGroup*>(main_group_->AddChild( |
| 602 base::WrapUnique(new PBXGroup(std::string(), "Product")))); | 645 base::WrapUnique(new PBXGroup(std::string(), "Product")))); |
| 603 main_group_->AddChild(base::WrapUnique(new PBXGroup(std::string(), "Build"))); | 646 main_group_->AddChild(base::WrapUnique(new PBXGroup(std::string(), "Build"))); |
| 604 | 647 |
| 605 configurations_.reset(new XCConfigurationList(config_name, attributes, this)); | 648 configurations_.reset(new XCConfigurationList(config_name, attributes, this)); |
| 606 } | 649 } |
| 607 | 650 |
| 608 PBXProject::~PBXProject() {} | 651 PBXProject::~PBXProject() {} |
| 609 | 652 |
| 610 void PBXProject::AddSourceFile(const std::string& source_path) { | 653 bool PBXProject::SourceFileShouldBeIndexed(const std::string& source_path) { |
| 654 base::StringPiece ext = FindExtension(&source_path); |
| 655 return IsSourceFileForIndexing(ext); |
| 656 } |
| 657 |
| 658 void PBXProject::AddSourceFile(const std::string& source_path, |
| 659 const std::string& cflags) { |
| 611 PBXFileReference* file_reference = sources_->AddSourceFile(source_path); | 660 PBXFileReference* file_reference = sources_->AddSourceFile(source_path); |
| 612 base::StringPiece ext = FindExtension(&source_path); | 661 if (!SourceFileShouldBeIndexed(source_path)) |
| 613 if (!IsSourceFileForIndexing(ext)) | |
| 614 return; | 662 return; |
| 615 | 663 |
| 616 if (!target_for_indexing_) { | 664 if (!target_for_indexing_) { |
| 617 PBXAttributes attributes; | 665 PBXAttributes attributes; |
| 618 attributes["EXECUTABLE_PREFIX"] = ""; | 666 attributes.insert(std::make_pair("EXECUTABLE_PREFIX", "")); |
| 619 attributes["HEADER_SEARCH_PATHS"] = sources_->path(); | 667 attributes.insert(std::make_pair("PRODUCT_NAME", name_)); |
| 620 attributes["PRODUCT_NAME"] = name_; | |
| 621 | 668 |
| 622 PBXFileReference* product_reference = static_cast<PBXFileReference*>( | 669 PBXFileReference* product_reference = static_cast<PBXFileReference*>( |
| 623 products_->AddChild(base::WrapUnique(new PBXFileReference( | 670 products_->AddChild(base::WrapUnique(new PBXFileReference( |
| 624 std::string(), name_, "compiled.mach-o.executable")))); | 671 std::string(), name_, "compiled.mach-o.executable")))); |
| 625 | 672 |
| 626 const char product_type[] = "com.apple.product-type.tool"; | 673 const char product_type[] = "com.apple.product-type.tool"; |
| 627 targets_.push_back(base::WrapUnique( | 674 targets_.push_back(base::WrapUnique( |
| 628 new PBXNativeTarget(name_, std::string(), config_name_, attributes, | 675 new PBXNativeTarget(name_, std::string(), config_name_, attributes, |
| 629 product_type, name_, product_reference))); | 676 product_type, name_, product_reference))); |
| 630 target_for_indexing_ = static_cast<PBXNativeTarget*>(targets_.back().get()); | 677 target_for_indexing_ = static_cast<PBXNativeTarget*>(targets_.back().get()); |
| 631 } | 678 } |
| 632 | 679 |
| 633 DCHECK(target_for_indexing_); | 680 DCHECK(target_for_indexing_); |
| 634 target_for_indexing_->AddFileForIndexing(file_reference); | 681 target_for_indexing_->AddFileForIndexing(file_reference, cflags); |
| 635 } | 682 } |
| 636 | 683 |
| 637 void PBXProject::AddAggregateTarget(const std::string& name, | 684 void PBXProject::AddAggregateTarget(const std::string& name, |
| 638 const std::string& shell_script) { | 685 const std::string& shell_script) { |
| 639 PBXAttributes attributes; | 686 PBXAttributes attributes; |
| 640 attributes["CODE_SIGNING_REQUIRED"] = "NO"; | 687 attributes.insert(std::make_pair("CODE_SIGNING_REQUIRED", "NO")); |
| 641 attributes["CONFIGURATION_BUILD_DIR"] = "."; | 688 attributes.insert(std::make_pair("CONFIGURATION_BUILD_DIR", ".")); |
| 642 attributes["PRODUCT_NAME"] = name; | 689 attributes.insert(std::make_pair("PRODUCT_NAME", name)); |
| 643 | 690 |
| 644 targets_.push_back(base::WrapUnique( | 691 targets_.push_back(base::WrapUnique( |
| 645 new PBXAggregateTarget(name, shell_script, config_name_, attributes))); | 692 new PBXAggregateTarget(name, shell_script, config_name_, attributes))); |
| 646 } | 693 } |
| 647 | 694 |
| 648 void PBXProject::AddNativeTarget(const std::string& name, | 695 void PBXProject::AddNativeTarget(const std::string& name, |
| 649 const std::string& type, | 696 const std::string& type, |
| 650 const std::string& output_name, | 697 const std::string& output_name, |
| 651 const std::string& output_type, | 698 const std::string& output_type, |
| 652 const std::string& shell_script) { | 699 const std::string& shell_script) { |
| 653 base::StringPiece ext = FindExtension(&output_name); | 700 base::StringPiece ext = FindExtension(&output_name); |
| 654 PBXFileReference* product = | 701 PBXFileReference* product = |
| 655 static_cast<PBXFileReference*>(products_->AddChild(base::WrapUnique( | 702 static_cast<PBXFileReference*>(products_->AddChild(base::WrapUnique( |
| 656 new PBXFileReference(std::string(), output_name, | 703 new PBXFileReference(std::string(), output_name, |
| 657 type.empty() ? GetSourceType(ext) : type)))); | 704 type.empty() ? GetSourceType(ext) : type)))); |
| 658 | 705 |
| 659 size_t ext_offset = FindExtensionOffset(output_name); | 706 size_t ext_offset = FindExtensionOffset(output_name); |
| 660 std::string product_name = ext_offset != std::string::npos | 707 std::string product_name = ext_offset != std::string::npos |
| 661 ? output_name.substr(0, ext_offset - 1) | 708 ? output_name.substr(0, ext_offset - 1) |
| 662 : output_name; | 709 : output_name; |
| 663 | 710 |
| 664 PBXAttributes attributes; | 711 PBXAttributes attributes; |
| 665 attributes["CODE_SIGNING_REQUIRED"] = "NO"; | 712 attributes.insert(std::make_pair("CODE_SIGNING_REQUIRED", "NO")); |
| 666 attributes["CONFIGURATION_BUILD_DIR"] = "."; | 713 attributes.insert(std::make_pair("CONFIGURATION_BUILD_DIR", ".")); |
| 667 attributes["PRODUCT_NAME"] = product_name; | 714 attributes.insert(std::make_pair("PRODUCT_NAME", product_name)); |
| 668 | 715 |
| 669 targets_.push_back(base::WrapUnique( | 716 targets_.push_back(base::WrapUnique( |
| 670 new PBXNativeTarget(name, shell_script, config_name_, attributes, | 717 new PBXNativeTarget(name, shell_script, config_name_, attributes, |
| 671 output_type, product_name, product))); | 718 output_type, product_name, product))); |
| 672 } | 719 } |
| 673 | 720 |
| 674 void PBXProject::SetProjectDirPath(const std::string& project_dir_path) { | 721 void PBXProject::SetProjectDirPath(const std::string& project_dir_path) { |
| 675 DCHECK(!project_dir_path.empty()); | 722 DCHECK(!project_dir_path.empty()); |
| 676 project_dir_path_.assign(project_dir_path); | 723 project_dir_path_.assign(project_dir_path); |
| 677 } | 724 } |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 const std::string indent_str(indent, '\t'); | 906 const std::string indent_str(indent, '\t'); |
| 860 const IndentRules rules = {false, indent + 1}; | 907 const IndentRules rules = {false, indent + 1}; |
| 861 out << indent_str << Reference() << " = {\n"; | 908 out << indent_str << Reference() << " = {\n"; |
| 862 PrintProperty(out, rules, "isa", ToString(Class())); | 909 PrintProperty(out, rules, "isa", ToString(Class())); |
| 863 PrintProperty(out, rules, "buildConfigurations", configurations_); | 910 PrintProperty(out, rules, "buildConfigurations", configurations_); |
| 864 PrintProperty(out, rules, "defaultConfigurationIsVisible", 1u); | 911 PrintProperty(out, rules, "defaultConfigurationIsVisible", 1u); |
| 865 PrintProperty(out, rules, "defaultConfigurationName", | 912 PrintProperty(out, rules, "defaultConfigurationName", |
| 866 configurations_[0]->Name()); | 913 configurations_[0]->Name()); |
| 867 out << indent_str << "};\n"; | 914 out << indent_str << "};\n"; |
| 868 } | 915 } |
| OLD | NEW |