Chromium Code Reviews| Index: tools/gn/xcode_writer.cc |
| diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc |
| index 5030b5abbb4e9f6947f0d7e708b174cc83c709da..dcb19e63e2756bcb13b47beb5b6f6b92bf44dbb7 100644 |
| --- a/tools/gn/xcode_writer.cc |
| +++ b/tools/gn/xcode_writer.cc |
| @@ -32,10 +32,16 @@ |
| namespace { |
| using TargetToFileList = std::unordered_map<const Target*, Target::FileList>; |
| +using TargetToNativeTarget = |
| + std::unordered_map<const Target*, PBXNativeTarget*>; |
| +using FileToTargets = std::map<SourceFile, |
| + std::vector<const Target*>, |
| + bool (*)(const SourceFile&, const SourceFile&)>; |
| const char kEarlGreyFileNameIdentifier[] = "egtest.mm"; |
| const char kXCTestFileNameIdentifier[] = "xctest.mm"; |
| const char kXCTestModuleTargetNamePostfix[] = "_module"; |
| +const char kXCTestFileReferenceFolder[] = "xctests/"; |
| struct SafeEnvironmentVariableInfo { |
| const char* name; |
| @@ -193,6 +199,31 @@ void FindXCTestFilesForTargets( |
| } |
| } |
| +// Maps each xctest file to a list of xctest application targets that contains |
| +// the file. |
| +void MapXCTestFileToApplicationTargets( |
| + const std::vector<const Target*>& xctest_application_targets, |
| + const std::vector<Target::FileList>& xctest_file_lists, |
| + FileToTargets* xctest_file_to_application_targets) { |
| + DCHECK_EQ(xctest_application_targets.size(), xctest_file_lists.size()); |
| + |
| + for (size_t i = 0; i < xctest_application_targets.size(); ++i) { |
| + const Target* xctest_application_target = xctest_application_targets[i]; |
| + DCHECK(IsApplicationTarget(xctest_application_target)); |
| + |
| + for (const SourceFile& source : xctest_file_lists[i]) { |
| + if (xctest_file_to_application_targets->find(source) == |
|
sdefresne
2017/01/05 12:14:02
I think you can avoid doing the search twice by us
liaoyuke
2017/01/05 17:43:12
Done.
|
| + xctest_file_to_application_targets->end()) { |
| + xctest_file_to_application_targets->insert( |
| + std::make_pair(source, std::vector<const Target*>())); |
| + } |
| + |
| + (*xctest_file_to_application_targets)[source].push_back( |
| + xctest_application_target); |
| + } |
| + } |
| +} |
| + |
| class CollectPBXObjectsPerClassHelper : public PBXObjectVisitor { |
| public: |
| CollectPBXObjectsPerClassHelper() {} |
| @@ -417,6 +448,8 @@ void XcodeWriter::CreateProductsProject( |
| main_project->AddAggregateTarget( |
| "All", GetBuildScript(root_target, ninja_extra_args, env.get())); |
| + TargetToNativeTarget xctest_application_to_module_native_target; |
| + |
| for (const Target* target : targets) { |
| switch (target->output_type()) { |
| case Target::EXECUTABLE: |
| @@ -447,7 +480,7 @@ void XcodeWriter::CreateProductsProject( |
| extra_attributes["DEBUG_INFORMATION_FORMAT"] = "dwarf"; |
| } |
| - main_project->AddNativeTarget( |
| + PBXNativeTarget* native_target = main_project->AddNativeTarget( |
| target->label().name(), std::string(), |
| RebasePath(target->bundle_data() |
| .GetBundleRootDirOutput(target->settings()) |
| @@ -456,6 +489,17 @@ void XcodeWriter::CreateProductsProject( |
| target->bundle_data().product_type(), |
| GetBuildScript(target->label().name(), ninja_extra_args, env.get()), |
| extra_attributes); |
| + |
| + if (!IsXCTestModuleTarget(target)) |
| + continue; |
| + |
| + // populate |xctest_application_to_module_native_target| for XCTest |
|
sdefresne
2017/01/05 12:14:02
s/populate/Populate/
liaoyuke
2017/01/05 17:43:12
Done.
|
| + // module targets. |
| + const Target* application_target = |
| + FindXCTestApplicationTarget(target, xctest_application_targets); |
| + xctest_application_to_module_native_target.insert( |
| + std::make_pair(application_target, native_target)); |
| + |
| break; |
| } |
| @@ -464,6 +508,42 @@ void XcodeWriter::CreateProductsProject( |
| } |
| } |
| + FileToTargets xctest_file_to_application_targets( |
|
sdefresne
2017/01/05 12:14:02
Please move this to be a real free function in the
liaoyuke
2017/01/05 17:43:12
Done.
|
| + [](const SourceFile& lhs, const SourceFile& rhs) { |
| + if (lhs.GetName() < rhs.GetName()) |
| + return true; |
| + else if (lhs.GetName() > rhs.GetName()) |
| + return false; |
| + else |
| + return lhs.value() < rhs.value(); |
| + }); |
| + MapXCTestFileToApplicationTargets(xctest_application_targets, |
| + xctest_file_lists, |
| + &xctest_file_to_application_targets); |
| + |
| + // Add xctest files to the "Compiler Sources" of corresponding xctest native |
| + // targets. |
| + SourceDir source_dir("//"); |
| + for (const auto& item : xctest_file_to_application_targets) { |
| + const SourceFile& source = item.first; |
| + for (const Target* xctest_application_target : item.second) { |
| + std::string navigator_path = |
| + kXCTestFileReferenceFolder + source.GetName(); |
| + std::string source_path = RebasePath(source.value(), source_dir, |
| + build_settings->root_path_utf8()); |
| + PBXNativeTarget* xctest_module_native_target = |
| + xctest_application_to_module_native_target[xctest_application_target]; |
| + |
| + // Test files need to be known to Xcode for proper indexing and for |
| + // discovery of tests function for XCTest, but the compilation is done |
| + // via ninja and thus must prevent Xcode from compiling the files by |
| + // adding '-help' as per file compiler flag. |
| + main_project->AddSourceFile(navigator_path, source_path, |
| + CompilerFlags::HELP, |
| + xctest_module_native_target); |
| + } |
| + } |
| + |
| projects_.push_back(std::move(main_project)); |
| } |