Chromium Code Reviews| 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_writer.h" | 5 #include "tools/gn/xcode_writer.h" |
| 6 | 6 |
| 7 #include <iomanip> | 7 #include <iomanip> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "tools/gn/filesystem_utils.h" | 24 #include "tools/gn/filesystem_utils.h" |
| 25 #include "tools/gn/settings.h" | 25 #include "tools/gn/settings.h" |
| 26 #include "tools/gn/source_file.h" | 26 #include "tools/gn/source_file.h" |
| 27 #include "tools/gn/target.h" | 27 #include "tools/gn/target.h" |
| 28 #include "tools/gn/value.h" | 28 #include "tools/gn/value.h" |
| 29 #include "tools/gn/variables.h" | 29 #include "tools/gn/variables.h" |
| 30 #include "tools/gn/xcode_object.h" | 30 #include "tools/gn/xcode_object.h" |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 using TargetToFileList = std::unordered_map<const Target*, Target::FileList>; | |
| 35 | |
| 36 const char kEarlGreyFileNameIdentifier[] = "egtest.mm"; | |
| 37 | |
|
justincohen
2016/12/15 00:30:24
Is there a better, less sticky way of finding Xcte
| |
| 34 struct SafeEnvironmentVariableInfo { | 38 struct SafeEnvironmentVariableInfo { |
| 35 const char* name; | 39 const char* name; |
| 36 bool capture_at_generation; | 40 bool capture_at_generation; |
| 37 }; | 41 }; |
| 38 | 42 |
| 39 SafeEnvironmentVariableInfo kSafeEnvironmentVariables[] = { | 43 SafeEnvironmentVariableInfo kSafeEnvironmentVariables[] = { |
| 40 {"HOME", true}, {"LANG", true}, {"PATH", true}, | 44 {"HOME", true}, {"LANG", true}, {"PATH", true}, |
| 41 {"USER", true}, {"TMPDIR", false}, | 45 {"USER", true}, {"TMPDIR", false}, |
| 42 }; | 46 }; |
| 43 | 47 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 | 83 |
| 80 script << "ninja -C ."; | 84 script << "ninja -C ."; |
| 81 if (!ninja_extra_args.empty()) | 85 if (!ninja_extra_args.empty()) |
| 82 script << " " << ninja_extra_args; | 86 script << " " << ninja_extra_args; |
| 83 if (!target_name.empty()) | 87 if (!target_name.empty()) |
| 84 script << " " << target_name; | 88 script << " " << target_name; |
| 85 script << "\nexit 1\n"; | 89 script << "\nexit 1\n"; |
| 86 return script.str(); | 90 return script.str(); |
| 87 } | 91 } |
| 88 | 92 |
| 93 // Finds the list of earl grey files recursively under |target|. | |
| 94 void GetEarlGreyFiles(const Target* target, | |
| 95 TargetToFileList* eg_files_per_target) { | |
| 96 // Early return if already visited and processed. | |
| 97 if (eg_files_per_target->find(target) != eg_files_per_target->end()) | |
| 98 return; | |
| 99 | |
| 100 Target::FileList eg_files; | |
| 101 for (const SourceFile& file : target->sources()) { | |
| 102 if (base::EndsWith(file.GetName(), kEarlGreyFileNameIdentifier, | |
| 103 base::CompareCase::SENSITIVE)) { | |
| 104 eg_files.push_back(file); | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 // Call recursively on public and private deps. | |
| 109 for (const auto& target : target->public_deps()) { | |
| 110 GetEarlGreyFiles(target.ptr, eg_files_per_target); | |
| 111 const Target::FileList& deps_eg_files = (*eg_files_per_target)[target.ptr]; | |
| 112 eg_files.insert(eg_files.end(), deps_eg_files.begin(), deps_eg_files.end()); | |
| 113 } | |
| 114 | |
| 115 for (const auto& target : target->private_deps()) { | |
| 116 GetEarlGreyFiles(target.ptr, eg_files_per_target); | |
| 117 const Target::FileList& deps_eg_files = (*eg_files_per_target)[target.ptr]; | |
| 118 eg_files.insert(eg_files.end(), deps_eg_files.begin(), deps_eg_files.end()); | |
| 119 } | |
| 120 | |
| 121 // Sort eg_files to remove duplicates. | |
| 122 std::sort(eg_files.begin(), eg_files.end()); | |
| 123 eg_files.erase(std::unique(eg_files.begin(), eg_files.end()), eg_files.end()); | |
| 124 | |
| 125 eg_files_per_target->insert(std::make_pair(target, eg_files)); | |
| 126 } | |
| 127 | |
| 128 // Finds the list of earl grey files recursively under each of the application | |
| 129 // target. | |
| 130 void GetEarlGreyFilesForAll( | |
| 131 const std::vector<const Target*>& application_targets, | |
| 132 std::vector<Target::FileList>* file_lists) { | |
| 133 TargetToFileList eg_files_per_target; | |
| 134 | |
| 135 for (const Target* target : application_targets) { | |
| 136 GetEarlGreyFiles(target, &eg_files_per_target); | |
| 137 file_lists->push_back(eg_files_per_target[target]); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 bool IsApplicationTarget(const Target* target) { | |
| 142 return target->output_type() == Target::CREATE_BUNDLE && | |
| 143 target->bundle_data().product_type() == | |
| 144 "com.apple.product-type.application"; | |
| 145 } | |
| 146 | |
| 89 class CollectPBXObjectsPerClassHelper : public PBXObjectVisitor { | 147 class CollectPBXObjectsPerClassHelper : public PBXObjectVisitor { |
| 90 public: | 148 public: |
| 91 CollectPBXObjectsPerClassHelper() {} | 149 CollectPBXObjectsPerClassHelper() {} |
| 92 | 150 |
| 93 void Visit(PBXObject* object) override { | 151 void Visit(PBXObject* object) override { |
| 94 DCHECK(object); | 152 DCHECK(object); |
| 95 objects_per_class_[object->Class()].push_back(object); | 153 objects_per_class_[object->Class()].push_back(object); |
| 96 } | 154 } |
| 97 | 155 |
| 98 const std::map<PBXObjectClass, std::vector<const PBXObject*>>& | 156 const std::map<PBXObjectClass, std::vector<const PBXObject*>>& |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 // Sort the list of targets per-label to get a consistent ordering of them | 317 // Sort the list of targets per-label to get a consistent ordering of them |
| 260 // in the generated Xcode project (and thus stability of the file generated). | 318 // in the generated Xcode project (and thus stability of the file generated). |
| 261 std::sort(targets->begin(), targets->end(), | 319 std::sort(targets->begin(), targets->end(), |
| 262 [](const Target* a, const Target* b) { | 320 [](const Target* a, const Target* b) { |
| 263 return a->label().name() < b->label().name(); | 321 return a->label().name() < b->label().name(); |
| 264 }); | 322 }); |
| 265 | 323 |
| 266 return true; | 324 return true; |
| 267 } | 325 } |
| 268 | 326 |
| 327 // static | |
| 328 void XcodeWriter::FilterApplicationTargets( | |
| 329 const std::vector<const Target*>& targets, | |
| 330 std::vector<const Target*>* application_targets) { | |
| 331 // Filter out all targets of type CREATE_BUNDLE and whose bundle_data has | |
| 332 // product_type: "com.apple.product-type.application". | |
| 333 for (const Target* target : targets) { | |
| 334 if (!IsApplicationTarget(target)) | |
| 335 continue; | |
| 336 | |
| 337 application_targets->push_back(target); | |
| 338 } | |
| 339 } | |
| 340 | |
| 269 void XcodeWriter::CreateProductsProject( | 341 void XcodeWriter::CreateProductsProject( |
| 270 const std::vector<const Target*>& targets, | 342 const std::vector<const Target*>& targets, |
| 271 const PBXAttributes& attributes, | 343 const PBXAttributes& attributes, |
| 272 const std::string& source_path, | 344 const std::string& source_path, |
| 273 const std::string& config_name, | 345 const std::string& config_name, |
| 274 const std::string& root_target, | 346 const std::string& root_target, |
| 275 const std::string& ninja_extra_args, | 347 const std::string& ninja_extra_args, |
| 276 const BuildSettings* build_settings, | 348 const BuildSettings* build_settings, |
| 277 TargetOsType target_os) { | 349 TargetOsType target_os) { |
| 278 std::unique_ptr<PBXProject> main_project( | 350 std::unique_ptr<PBXProject> main_project( |
| 279 new PBXProject("products", config_name, source_path, attributes)); | 351 new PBXProject("products", config_name, source_path, attributes)); |
| 280 | 352 |
| 353 // Filter application targets and find list of earl grey test files | |
| 354 // recursively under them. | |
| 355 std::vector<const Target*> xctest_targets; | |
| 356 std::vector<const Target*> application_targets; | |
| 357 std::vector<Target::FileList> earl_grey_file_lists; | |
| 358 XcodeWriter::FilterApplicationTargets(targets, &application_targets); | |
| 359 GetEarlGreyFilesForAll(application_targets, &earl_grey_file_lists); | |
| 360 | |
| 281 std::string build_path; | 361 std::string build_path; |
| 282 std::unique_ptr<base::Environment> env(base::Environment::Create()); | 362 std::unique_ptr<base::Environment> env(base::Environment::Create()); |
| 283 | 363 |
| 284 main_project->AddAggregateTarget( | 364 main_project->AddAggregateTarget( |
| 285 "All", GetBuildScript(root_target, ninja_extra_args, env.get())); | 365 "All", GetBuildScript(root_target, ninja_extra_args, env.get())); |
| 286 | 366 |
| 287 for (const Target* target : targets) { | 367 for (const Target* target : targets) { |
| 288 switch (target->output_type()) { | 368 switch (target->output_type()) { |
| 289 case Target::EXECUTABLE: | 369 case Target::EXECUTABLE: |
| 290 if (target_os == XcodeWriter::WRITER_TARGET_OS_IOS) | 370 if (target_os == XcodeWriter::WRITER_TARGET_OS_IOS) |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 for (auto* object : pair.second) { | 507 for (auto* object : pair.second) { |
| 428 object->Print(out, 2); | 508 object->Print(out, 2); |
| 429 } | 509 } |
| 430 out << "/* End " << ToString(pair.first) << " section */\n"; | 510 out << "/* End " << ToString(pair.first) << " section */\n"; |
| 431 } | 511 } |
| 432 | 512 |
| 433 out << "\t};\n" | 513 out << "\t};\n" |
| 434 << "\trootObject = " << project->Reference() << ";\n" | 514 << "\trootObject = " << project->Reference() << ";\n" |
| 435 << "}\n"; | 515 << "}\n"; |
| 436 } | 516 } |
| OLD | NEW |