Index: tools/gn/xcode_writer.cc |
diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc |
index a780d80a8abadfb2d5d302704ff639aa4ca0150a..41af6289bd6010491acc7be3cdb330798b6c0f3e 100644 |
--- a/tools/gn/xcode_writer.cc |
+++ b/tools/gn/xcode_writer.cc |
@@ -32,16 +32,11 @@ |
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&)>; |
+using TargetToTarget = std::unordered_map<const Target*, const Target*>; |
const char kEarlGreyFileNameIdentifier[] = "egtest.mm"; |
const char kXCTestFileNameIdentifier[] = "xctest.mm"; |
const char kXCTestModuleTargetNamePostfix[] = "_module"; |
-const char kXCTestFileReferenceFolder[] = "xctests/"; |
struct SafeEnvironmentVariableInfo { |
const char* name; |
@@ -53,15 +48,6 @@ SafeEnvironmentVariableInfo kSafeEnvironmentVariables[] = { |
{"USER", true}, {"TMPDIR", false}, |
}; |
-bool CompareSourceFiles(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(); |
-} |
- |
XcodeWriter::TargetOsType GetTargetOs(const Args& args) { |
const Value* target_os_value = args.GetArgOverride(variables::kTargetOs); |
if (target_os_value) { |
@@ -121,6 +107,13 @@ bool IsXCTestModuleTarget(const Target* target) { |
base::CompareCase::SENSITIVE); |
} |
+bool IsXCTestFile(const SourceFile& file) { |
+ return base::EndsWith(file.GetName(), kEarlGreyFileNameIdentifier, |
+ base::CompareCase::SENSITIVE) || |
+ base::EndsWith(file.GetName(), kXCTestFileNameIdentifier, |
+ base::CompareCase::SENSITIVE); |
+} |
+ |
const Target* FindXCTestApplicationTarget( |
const Target* xctest_module_target, |
const std::vector<const Target*>& targets) { |
@@ -141,14 +134,18 @@ const Target* FindXCTestApplicationTarget( |
return nullptr; |
} |
-// Returns the corresponding application targets given XCTest module targets. |
+// Given XCTest module targets, find the corresponding application targets and |
+// the mappings between them. |
void FindXCTestApplicationTargets( |
const std::vector<const Target*>& xctest_module_targets, |
const std::vector<const Target*>& targets, |
- std::vector<const Target*>* xctest_application_targets) { |
+ std::vector<const Target*>* xctest_application_targets, |
+ TargetToTarget* xctest_module_to_application_target) { |
for (const Target* xctest_module_target : xctest_module_targets) { |
xctest_application_targets->push_back( |
FindXCTestApplicationTarget(xctest_module_target, targets)); |
+ xctest_module_to_application_target->insert(std::make_pair( |
+ xctest_module_target, xctest_application_targets->back())); |
} |
} |
@@ -161,10 +158,7 @@ void SearchXCTestFiles(const Target* target, |
Target::FileList xctest_files; |
for (const SourceFile& file : target->sources()) { |
- if (base::EndsWith(file.GetName(), kEarlGreyFileNameIdentifier, |
- base::CompareCase::SENSITIVE) || |
- base::EndsWith(file.GetName(), kXCTestFileNameIdentifier, |
- base::CompareCase::SENSITIVE)) { |
+ if (IsXCTestFile(file)) { |
xctest_files.push_back(file); |
} |
} |
@@ -196,40 +190,15 @@ void SearchXCTestFiles(const Target* target, |
// Finds the list of xctest files recursively under each of the application |
// targets. |
-void FindXCTestFilesForTargets( |
+void FindXCTestFilesForApplicationTargets( |
const std::vector<const Target*>& application_targets, |
- std::vector<Target::FileList>* file_lists) { |
+ TargetToFileList* xctest_files_per_application_target) { |
TargetToFileList xctest_files_per_target; |
- |
for (const Target* target : application_targets) { |
DCHECK(IsApplicationTarget(target)); |
SearchXCTestFiles(target, &xctest_files_per_target); |
- file_lists->push_back(xctest_files_per_target[target]); |
- } |
-} |
- |
-// 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]) { |
- auto iter = xctest_file_to_application_targets->find(source); |
- if (iter == xctest_file_to_application_targets->end()) { |
- iter = |
- xctest_file_to_application_targets |
- ->insert(std::make_pair(source, std::vector<const Target*>())) |
- .first; |
- } |
- iter->second.push_back(xctest_application_target); |
- } |
+ xctest_files_per_application_target->insert( |
+ std::make_pair(target, xctest_files_per_target[target])); |
} |
} |
@@ -341,13 +310,9 @@ bool XcodeWriter::RunAndWriteFiles(const std::string& workspace_name, |
} |
XcodeWriter workspace(workspace_name); |
- workspace.CreateProductsProject(targets, attributes, source_path, config_name, |
- root_target_name, ninja_extra_args, |
- build_settings, target_os); |
- |
- workspace.CreateSourcesProject( |
- all_targets, build_settings->build_dir(), attributes, source_path, |
- build_settings->root_path_utf8(), config_name, target_os); |
+ workspace.CreateProductsProject(targets, all_targets, attributes, source_path, |
+ config_name, root_target_name, |
+ ninja_extra_args, build_settings, target_os); |
return workspace.WriteFiles(build_settings, err); |
} |
@@ -427,6 +392,7 @@ void XcodeWriter::FilterXCTestModuleTargets( |
void XcodeWriter::CreateProductsProject( |
const std::vector<const Target*>& targets, |
+ const std::vector<const Target*>& all_targets, |
const PBXAttributes& attributes, |
const std::string& source_path, |
const std::string& config_name, |
@@ -436,20 +402,53 @@ void XcodeWriter::CreateProductsProject( |
TargetOsType target_os) { |
std::unique_ptr<PBXProject> main_project( |
new PBXProject("products", config_name, source_path, attributes)); |
+ SourceDir source_dir("//"); |
+ |
+ // Add all source files for indexing. |
+ std::vector<SourceFile> sources; |
+ for (const Target* target : all_targets) { |
+ for (const SourceFile& source : target->sources()) { |
+ if (IsStringInOutputDir(build_settings->build_dir(), source.value())) |
+ continue; |
+ |
+ sources.push_back(source); |
+ } |
+ } |
+ |
+ // Sort sources to ensure determinisn of the project file generation and |
+ // remove duplicate reference to the source files (can happen due to the |
+ // bundle_data targets). |
+ std::sort(sources.begin(), sources.end()); |
+ sources.erase(std::unique(sources.begin(), sources.end()), sources.end()); |
+ |
+ for (const SourceFile& source : sources) { |
+ std::string source_file = RebasePath(source.value(), source_dir, |
+ build_settings->root_path_utf8()); |
+ main_project->AddSourceFileToIndexingTarget(source_file, source_file, |
+ CompilerFlags::NONE); |
+ } |
// Filter xctest module and application targets and find list of xctest files |
// recursively under them. |
std::vector<const Target*> xctest_module_targets; |
FilterXCTestModuleTargets(targets, &xctest_module_targets); |
+ // There is a 1 on 1 mapping between |xctest_module_targets| and |
+ // |xctest_application_targets|. |
std::vector<const Target*> xctest_application_targets; |
+ TargetToTarget xctest_module_to_application_target; |
FindXCTestApplicationTargets(xctest_module_targets, targets, |
- &xctest_application_targets); |
+ &xctest_application_targets, |
+ &xctest_module_to_application_target); |
DCHECK_EQ(xctest_module_targets.size(), xctest_application_targets.size()); |
+ DCHECK_EQ(xctest_module_targets.size(), |
+ xctest_module_to_application_target.size()); |
- std::vector<Target::FileList> xctest_file_lists; |
- FindXCTestFilesForTargets(xctest_application_targets, &xctest_file_lists); |
- DCHECK_EQ(xctest_application_targets.size(), xctest_file_lists.size()); |
+ TargetToFileList xctest_files_per_application_target; |
+ FindXCTestFilesForApplicationTargets(xctest_application_targets, |
+ &xctest_files_per_application_target); |
+ DCHECK_EQ(xctest_application_targets.size(), |
+ xctest_files_per_application_target.size()); |
std::string build_path; |
std::unique_ptr<base::Environment> env(base::Environment::Create()); |
@@ -457,8 +456,6 @@ 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: |
@@ -502,12 +499,23 @@ void XcodeWriter::CreateProductsProject( |
if (!IsXCTestModuleTarget(target)) |
continue; |
- // Populate |xctest_application_to_module_native_target| for XCTest |
- // 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)); |
+ // Add xctest files to the "Compiler Sources" of corresponding xctest |
+ // native targets. |
+ const Target::FileList& xctest_file_list = |
+ xctest_files_per_application_target |
+ [xctest_module_to_application_target[target]]; |
+ |
+ for (const SourceFile& source : xctest_file_list) { |
+ std::string source_path = RebasePath( |
+ source.value(), source_dir, build_settings->root_path_utf8()); |
+ |
+ // 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(source_path, source_path, |
+ CompilerFlags::HELP, native_target); |
+ } |
break; |
} |
@@ -517,75 +525,9 @@ void XcodeWriter::CreateProductsProject( |
} |
} |
- FileToTargets xctest_file_to_application_targets(CompareSourceFiles); |
- 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)); |
} |
-void XcodeWriter::CreateSourcesProject( |
- const std::vector<const Target*>& targets, |
- const SourceDir& root_build_dir, |
- const PBXAttributes& attributes, |
- const std::string& source_path, |
- const std::string& absolute_source_path, |
- const std::string& config_name, |
- TargetOsType target_os) { |
- std::vector<SourceFile> sources; |
- for (const Target* target : targets) { |
- for (const SourceFile& source : target->sources()) { |
- if (IsStringInOutputDir(root_build_dir, source.value())) |
- continue; |
- |
- sources.push_back(source); |
- } |
- } |
- |
- std::unique_ptr<PBXProject> sources_for_indexing( |
- new PBXProject("sources", config_name, source_path, attributes)); |
- |
- // Sort sources to ensure determinisn of the project file generation and |
- // remove duplicate reference to the source files (can happen due to the |
- // bundle_data targets). |
- std::sort(sources.begin(), sources.end()); |
- sources.erase(std::unique(sources.begin(), sources.end()), sources.end()); |
- |
- SourceDir source_dir("//"); |
- for (const SourceFile& source : sources) { |
- std::string source_file = |
- RebasePath(source.value(), source_dir, absolute_source_path); |
- sources_for_indexing->AddSourceFileToIndexingTarget( |
- source_file, source_file, CompilerFlags::NONE); |
- } |
- |
- projects_.push_back(std::move(sources_for_indexing)); |
-} |
- |
bool XcodeWriter::WriteFiles(const BuildSettings* build_settings, Err* err) { |
for (const auto& project : projects_) { |
if (!WriteProjectFile(build_settings, project.get(), err)) |