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

Unified Diff: tools/gn/xcode_writer.cc

Issue 2057873002: [GN] Export include directories, defines and dialects to Xcode projects Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months 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 side-by-side diff with in-line comments
Download patch
« tools/gn/xcode_object.cc ('K') | « tools/gn/xcode_object.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/xcode_writer.cc
diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc
index 10624fa180d54a5d1df9067d8ca04ea720d5bb2d..09800a2dfb9735cf0dd2edde87783264f135c6d6 100644
--- a/tools/gn/xcode_writer.cc
+++ b/tools/gn/xcode_writer.cc
@@ -20,6 +20,7 @@
#include "tools/gn/build_settings.h"
#include "tools/gn/builder.h"
#include "tools/gn/commands.h"
+#include "tools/gn/config_values_extractors.h"
#include "tools/gn/deps_iterator.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/settings.h"
@@ -316,6 +317,183 @@ void XcodeWriter::CreateProductsProject(
projects_.push_back(std::move(main_project));
}
+namespace {
+
+template <typename T>
+void SortAndRemoveDuplicates(std::vector<T>& vec) {
+ std::sort(vec.begin(), vec.end());
+ vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
+}
+
+template <typename T>
+std::vector<T> IntersectSortedVectors(const std::vector<T>& vec,
+ const std::vector<T>& vec2) {
+ std::vector<T> intersection;
+ std::set_intersection(vec.begin(), vec.end(), vec2.begin(), vec2.end(),
+ std::back_inserter(intersection));
+ return intersection;
+}
+
+template <typename T>
+std::vector<T> ExcludeSortedVectors(const std::vector<T>& from,
+ const std::vector<T>& what) {
+ std::vector<T> difference;
+ std::set_difference(from.begin(), from.end(), what.begin(), what.end(),
+ std::back_inserter(difference));
+ return difference;
+}
+
+void ExtractDialect(std::string& res,
+ const std::vector<std::string>& flags,
+ bool cc) {
+ for (const auto& flag : flags) {
+ if (res.empty() && flag.compare(0, 5, "-std=") == 0) {
+ res = flag;
+ }
+ if (!res.empty()) {
+ break;
+ }
+ }
+
+ // we're looking for c++ dialect, it must have + in name
+ if (cc && res.find('+') == std::string::npos)
+ res.clear();
+
+ // we're looking for c dialect, it must not have + in name
+ if (!cc && res.find('+') != std::string::npos)
+ res.clear();
+}
+
+void PrepareBuildAttributes(const std::vector<const Target*>& indexed_targets,
+ const SourceDir& root_build_dir,
+ std::map<SourceFile, std::string> & cflags,
+ PBXAttributes & attributes) {
+ std::vector<SourceDir> common_includes;
+ std::vector<std::string> common_defines;
+
+ for (const auto* target : indexed_targets) {
+ std::vector<SourceDir> target_includes;
+ std::vector<std::string> target_defines;
+
+ for (ConfigValuesIterator it(target); !it.done(); it.Next()) {
+ target_includes.insert(target_includes.end(),
+ it.cur().include_dirs().begin(),
+ it.cur().include_dirs().end());
+ target_defines.insert(target_defines.end(),
+ it.cur().defines().begin(),
+ it.cur().defines().end());
+ }
+ SortAndRemoveDuplicates(target_includes);
+ SortAndRemoveDuplicates(target_defines);
+
+ if (target == indexed_targets.front()) {
+ common_includes = std::move(target_includes);
+ common_defines = std::move(target_defines);
+ } else {
+ if (common_includes.empty() && common_defines.empty())
+ break;
+ common_includes = IntersectSortedVectors(common_includes,
+ target_includes);
+ common_defines = IntersectSortedVectors(common_defines,
+ target_defines);
+ }
+ }
+
+ for (const auto* target : indexed_targets) {
+ std::vector<SourceDir> target_includes;
+ std::vector<std::string> target_defines;
+
+ std::string target_dialect_c;
+ std::string target_dialect_cc;
+ std::string target_dialect_objc;
+ std::string target_dialect_objcc;
+
+ for (ConfigValuesIterator it(target); !it.done(); it.Next()) {
+ target_includes.insert(target_includes.end(),
+ it.cur().include_dirs().begin(),
+ it.cur().include_dirs().end());
+ target_defines.insert(target_defines.end(),
+ it.cur().defines().begin(),
+ it.cur().defines().end());
+
+ ExtractDialect(target_dialect_c, it.cur().cflags_c(), false);
+ ExtractDialect(target_dialect_c, it.cur().cflags(), false);
+ ExtractDialect(target_dialect_cc, it.cur().cflags_cc(), true);
+ ExtractDialect(target_dialect_cc, it.cur().cflags(), true);
+ ExtractDialect(target_dialect_objc, it.cur().cflags_objc(), false);
+ ExtractDialect(target_dialect_objc, it.cur().cflags(), false);
+ ExtractDialect(target_dialect_objcc, it.cur().cflags_objcc(), true);
+ ExtractDialect(target_dialect_objcc, it.cur().cflags(), true);
+ }
+ SortAndRemoveDuplicates(target_includes);
+ SortAndRemoveDuplicates(target_defines);
+
+ std::string target_cflags;
+
+ target_includes = ExcludeSortedVectors(target_includes, common_includes);
+ for (const auto& include : target_includes) {
+ std::string rebased = include.is_system_absolute()
+ ? include.value()
+ : RebasePath(include.value(), root_build_dir);
+ target_cflags += " -I";
+ target_cflags += rebased;
+ }
+
+ target_defines = ExcludeSortedVectors(target_defines, common_defines);
+ for (const auto& define : target_defines) {
+ target_cflags += " -D";
+ target_cflags += define;
+ }
+
+ if (!target_cflags.empty())
+ target_cflags = target_cflags.substr(1);
+
+ for (const SourceFile& source : target->sources()) {
+ std::string file_cflags = target_cflags;
+ std::string file_dialect;
+ const auto& ext = FindExtension(&source.value());
+ if (ext == "c")
+ file_dialect = target_dialect_c;
+ else if (ext == "cc" || ext == "cpp" || ext == "cxx")
+ file_dialect = target_dialect_cc;
+ else if (ext == "m")
+ file_dialect = target_dialect_objc;
+ else if (ext == "mm")
+ file_dialect = target_dialect_objcc;
+
+ if (!file_cflags.empty() && !file_dialect.empty())
+ file_cflags += " ";
+ file_cflags += file_dialect;
+
+ cflags[source] = file_cflags;
+ }
+ }
+
+ attributes["USE_HEADERMAP"] = "NO";
+
+ if (!common_includes.empty()) {
+ std::string includes;
+ for (const auto& include : common_includes) {
+ includes += include.is_system_absolute()
+ ? include.value()
+ : RebasePath(include.value(), root_build_dir);
+ includes += "\n";
+ }
+ attributes["HEADER_SEARCH_PATHS"] = includes;
+ }
+
+ if (!common_defines.empty()) {
+ std::string defines;
+ for (const auto& define : common_defines) {
+ defines += define;
+ defines += "\n";
+ }
+ attributes["GCC_PREPROCESSOR_DEFINITIONS"] = defines;
+ }
+}
+
+} // namespace
+
void XcodeWriter::CreateSourcesProject(
const std::vector<const Target*>& targets,
const SourceDir& root_build_dir,
@@ -323,7 +501,10 @@ void XcodeWriter::CreateSourcesProject(
const std::string& source_path,
const std::string& config_name,
TargetOsType target_os) {
+
std::vector<SourceFile> sources;
+ std::vector<const Target*> indexed_targets;
+
for (const Target* target : targets) {
if (!target->settings()->is_default())
continue;
@@ -336,22 +517,31 @@ void XcodeWriter::CreateSourcesProject(
continue;
sources.push_back(source);
+
+ if (PBXProject::SourceFileShouldBeIndexed(source.value()) &&
+ (indexed_targets.empty() || indexed_targets.back() != target)) {
+ indexed_targets.push_back(target);
+ }
}
}
+ std::map<SourceFile, std::string> cflags;
+ PBXAttributes updated_attributes(attributes);
+ PrepareBuildAttributes(indexed_targets, root_build_dir, cflags,
+ updated_attributes);
+
std::unique_ptr<PBXProject> sources_for_indexing(
- new PBXProject("sources", config_name, source_path, attributes));
+ new PBXProject("sources", config_name, source_path, updated_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());
+ SortAndRemoveDuplicates(sources);
SourceDir source_dir("//");
for (const SourceFile& source : sources) {
std::string source_file = RebasePath(source.value(), source_dir);
- sources_for_indexing->AddSourceFile(source_file);
+ sources_for_indexing->AddSourceFile(source_file, cflags[source]);
}
projects_.push_back(std::move(sources_for_indexing));
« tools/gn/xcode_object.cc ('K') | « tools/gn/xcode_object.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698