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

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

Issue 2574643002: Add functionality to find xctest files under application target. (Closed)
Patch Set: Update comments Created 4 years 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
« tools/gn/xcode_writer.h ('K') | « tools/gn/xcode_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 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
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 const char kXCTestTargetNamePostfix[] = "_module";
35 const char kEarlGreyFileNameIdentifier[] = "egtest.mm";
36
37 typedef std::unordered_map<const Target*, Target::FileList> TargetToFileList;
sdefresne 2016/12/14 13:00:03 nit: it is recommend to use "using" instead of "ty
liaoyuke 2016/12/15 00:03:11 Done.
38
34 struct SafeEnvironmentVariableInfo { 39 struct SafeEnvironmentVariableInfo {
35 const char* name; 40 const char* name;
36 bool capture_at_generation; 41 bool capture_at_generation;
37 }; 42 };
38 43
39 SafeEnvironmentVariableInfo kSafeEnvironmentVariables[] = { 44 SafeEnvironmentVariableInfo kSafeEnvironmentVariables[] = {
40 {"HOME", true}, {"LANG", true}, {"PATH", true}, 45 {"HOME", true}, {"LANG", true}, {"PATH", true},
41 {"USER", true}, {"TMPDIR", false}, 46 {"USER", true}, {"TMPDIR", false},
42 }; 47 };
43 48
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 85
81 script << "ninja -C ."; 86 script << "ninja -C .";
82 if (!ninja_extra_args.empty()) 87 if (!ninja_extra_args.empty())
83 script << " " << ninja_extra_args; 88 script << " " << ninja_extra_args;
84 if (!target_name.empty()) 89 if (!target_name.empty())
85 script << " " << target_name; 90 script << " " << target_name;
86 script << "\nexit 1\n"; 91 script << "\nexit 1\n";
87 return script.str(); 92 return script.str();
88 } 93 }
89 94
95 // Append |file_list_extra| to |file_list_base| and remove duplicate elements.
96 void AppendAndRemoveDuplicates(Target::FileList* file_list_base,
97 const Target::FileList& file_list_extra) {
98 file_list_base->insert(file_list_base->end(), file_list_extra.begin(),
99 file_list_extra.end());
100 std::sort(file_list_base->begin(), file_list_base->end());
101 file_list_base->erase(
102 std::unique(file_list_base->begin(), file_list_base->end()),
103 file_list_base->end());
104 }
105
106 // Find the list of earl grey files recursively under |target|.
107 void GetEarlGreyFiles(const Target* target,
108 TargetToFileList* eg_files_per_target) {
109 // Early return if already visited and processed.
110 if (eg_files_per_target->find(target) != eg_files_per_target->end()) {
sdefresne 2016/12/14 13:00:03 No braces here (since there are not used in the re
liaoyuke 2016/12/15 00:03:11 Done.
111 return;
112 }
113
114 Target::FileList eg_files;
115 for (const SourceFile& file : target->sources()) {
116 if (base::EndsWith(file.GetName(), kEarlGreyFileNameIdentifier,
117 base::CompareCase::SENSITIVE)) {
118 eg_files.push_back(file);
119 }
120 }
121
122 // Call recursively on public and private deps.
123 for (const auto& target : target->public_deps()) {
124 GetEarlGreyFiles(target.ptr, eg_files_per_target);
125 Target::FileList deps_eg_files = eg_files_per_target->at(target.ptr);
126 if (!deps_eg_files.empty()) {
sdefresne 2016/12/14 13:00:02 No braces here.
liaoyuke 2016/12/15 00:03:11 Done.
127 AppendAndRemoveDuplicates(&eg_files, deps_eg_files);
sdefresne 2016/12/14 13:00:03 I think it would be better to just add everything
liaoyuke 2016/12/15 00:03:11 Done.
128 }
129 }
130
131 for (const auto& target : target->private_deps()) {
132 GetEarlGreyFiles(target.ptr, eg_files_per_target);
133 Target::FileList deps_eg_files = eg_files_per_target->at(target.ptr);
134 if (!deps_eg_files.empty()) {
135 AppendAndRemoveDuplicates(&eg_files, deps_eg_files);
136 }
137 }
138
139 // Sort eg_files to remove duplicates.
140 std::sort(eg_files.begin(), eg_files.end());
141 eg_files.erase(std::unique(eg_files.begin(), eg_files.end()), eg_files.end());
142
143 eg_files_per_target->insert(std::make_pair(target, eg_files));
144 }
145
146 // Find the list of earl grey files recursively under each of the application
sdefresne 2016/12/14 13:00:02 nit: Find -> Finds
liaoyuke 2016/12/15 00:03:11 Done.
147 // and xctest bundle pair.
148 void GetEarlGreyFilesForAll(
sdefresne 2016/12/14 13:00:02 I'm not sure we need to check source file in xctes
liaoyuke 2016/12/15 00:03:11 You are right, I have double-checked, there is no
149 const std::vector<const Target*>& xctest_targets,
150 const std::vector<const Target*>& application_targets,
151 std::vector<Target::FileList>* file_lists) {
sdefresne 2016/12/14 13:00:03 DCHECK_EQ(xctest_targets.size(), application_targe
liaoyuke 2016/12/15 00:03:11 Acknowledged.
152 TargetToFileList eg_files_per_target;
153
154 for (size_t i = 0; i < xctest_targets.size(); ++i) {
155 GetEarlGreyFiles(xctest_targets[i], &eg_files_per_target);
156 GetEarlGreyFiles(application_targets[i], &eg_files_per_target);
157
158 Target::FileList eg_files;
159 AppendAndRemoveDuplicates(&eg_files,
160 eg_files_per_target.at(xctest_targets[i]));
161 AppendAndRemoveDuplicates(&eg_files,
162 eg_files_per_target.at(application_targets[i]));
163 file_lists->push_back(eg_files);
164 }
165 }
166
167 // Returns the corresponding application target given a XCTest target. Returns
sdefresne 2016/12/14 13:00:03 I would change this function to DCHECK if it does
liaoyuke 2016/12/15 00:03:11 Thank you for the note. I will this logic when I w
liaoyuke 2016/12/15 00:03:11 Acknowledged.
168 // NULL if not found.
169 const Target* FindApplicationTarget(const Target* xctest_target,
170 const std::vector<const Target*>& targets) {
171 for (const Target* target : targets) {
172 if ((target->label().name() + kXCTestTargetNamePostfix)
173 .compare(xctest_target->label().name()) == 0) {
174 return target;
175 }
176 }
177
178 return NULL;
179 }
180
90 class CollectPBXObjectsPerClassHelper : public PBXObjectVisitor { 181 class CollectPBXObjectsPerClassHelper : public PBXObjectVisitor {
91 public: 182 public:
92 CollectPBXObjectsPerClassHelper() {} 183 CollectPBXObjectsPerClassHelper() {}
93 184
94 void Visit(PBXObject* object) override { 185 void Visit(PBXObject* object) override {
95 DCHECK(object); 186 DCHECK(object);
96 objects_per_class_[object->Class()].push_back(object); 187 objects_per_class_[object->Class()].push_back(object);
97 } 188 }
98 189
99 const std::map<PBXObjectClass, std::vector<const PBXObject*>>& 190 const std::map<PBXObjectClass, std::vector<const PBXObject*>>&
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 // Sort the list of targets per-label to get a consistent ordering of them 351 // Sort the list of targets per-label to get a consistent ordering of them
261 // in the generated Xcode project (and thus stability of the file generated). 352 // in the generated Xcode project (and thus stability of the file generated).
262 std::sort(targets->begin(), targets->end(), 353 std::sort(targets->begin(), targets->end(),
263 [](const Target* a, const Target* b) { 354 [](const Target* a, const Target* b) {
264 return a->label().name() < b->label().name(); 355 return a->label().name() < b->label().name();
265 }); 356 });
266 357
267 return true; 358 return true;
268 } 359 }
269 360
361 // static
362 void XcodeWriter::FilterXCTestTargets(
363 const std::vector<const Target*>& targets,
364 std::vector<const Target*>* xctest_targets,
365 std::vector<const Target*>* application_targets) {
366 // Filter out all targets of type CREATE_BUNDLE and whose bundle_data has
367 // product_type: "com.apple.product-type.bundle.unit-test".
368 for (const Target* target : targets) {
369 if (target->output_type() != Target::CREATE_BUNDLE) {
sdefresne 2016/12/14 13:00:02 nit: I would use an helper method IsXCTestTarget h
370 continue;
371 }
372 if (target->bundle_data().product_type().compare(
373 "com.apple.product-type.bundle.unit-test") == 0) {
374 xctest_targets->push_back(target);
375 const Target* application_target = FindApplicationTarget(target, targets);
376 DCHECK(application_target);
377 application_targets->push_back(application_target);
378 }
379 }
380 }
381
270 void XcodeWriter::CreateProductsProject( 382 void XcodeWriter::CreateProductsProject(
271 const std::vector<const Target*>& targets, 383 const std::vector<const Target*>& targets,
272 const PBXAttributes& attributes, 384 const PBXAttributes& attributes,
273 const std::string& source_path, 385 const std::string& source_path,
274 const std::string& config_name, 386 const std::string& config_name,
275 const std::string& root_target, 387 const std::string& root_target,
276 const std::string& ninja_extra_args, 388 const std::string& ninja_extra_args,
277 const BuildSettings* build_settings, 389 const BuildSettings* build_settings,
278 TargetOsType target_os) { 390 TargetOsType target_os) {
279 std::unique_ptr<PBXProject> main_project( 391 std::unique_ptr<PBXProject> main_project(
280 new PBXProject("products", config_name, source_path, attributes)); 392 new PBXProject("products", config_name, source_path, attributes));
281 393
394 // Filter XCTest targets and their corresponding application targets and find
395 // list of earl grey test files recursively under the pairs.
396 std::vector<const Target*> xctest_targets;
397 std::vector<const Target*> application_targets;
398 std::vector<Target::FileList> earl_grey_file_lists;
399 XcodeWriter::FilterXCTestTargets(targets, &xctest_targets,
400 &application_targets);
401 GetEarlGreyFilesForAll(xctest_targets, application_targets,
402 &earl_grey_file_lists);
403
282 std::string build_path; 404 std::string build_path;
283 std::unique_ptr<base::Environment> env(base::Environment::Create()); 405 std::unique_ptr<base::Environment> env(base::Environment::Create());
284 406
285 main_project->AddAggregateTarget( 407 main_project->AddAggregateTarget(
286 "All", GetBuildScript(root_target, ninja_extra_args, env.get())); 408 "All", GetBuildScript(root_target, ninja_extra_args, env.get()));
287 409
288 for (const Target* target : targets) { 410 for (const Target* target : targets) {
289 switch (target->output_type()) { 411 switch (target->output_type()) {
290 case Target::EXECUTABLE: 412 case Target::EXECUTABLE:
291 if (target_os == XcodeWriter::WRITER_TARGET_OS_IOS) 413 if (target_os == XcodeWriter::WRITER_TARGET_OS_IOS)
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 for (auto* object : pair.second) { 550 for (auto* object : pair.second) {
429 object->Print(out, 2); 551 object->Print(out, 2);
430 } 552 }
431 out << "/* End " << ToString(pair.first) << " section */\n"; 553 out << "/* End " << ToString(pair.first) << " section */\n";
432 } 554 }
433 555
434 out << "\t};\n" 556 out << "\t};\n"
435 << "\trootObject = " << project->Reference() << ";\n" 557 << "\trootObject = " << project->Reference() << ";\n"
436 << "}\n"; 558 << "}\n";
437 } 559 }
OLDNEW
« tools/gn/xcode_writer.h ('K') | « tools/gn/xcode_writer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698