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

Side by Side 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 unified diff | Download patch
« tools/gn/xcode_object.cc ('K') | « tools/gn/xcode_object.cc ('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>
11 #include <string> 11 #include <string>
12 #include <utility> 12 #include <utility>
13 13
14 #include "base/environment.h" 14 #include "base/environment.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/sha1.h" 16 #include "base/sha1.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "tools/gn/args.h" 19 #include "tools/gn/args.h"
20 #include "tools/gn/build_settings.h" 20 #include "tools/gn/build_settings.h"
21 #include "tools/gn/builder.h" 21 #include "tools/gn/builder.h"
22 #include "tools/gn/commands.h" 22 #include "tools/gn/commands.h"
23 #include "tools/gn/config_values_extractors.h"
23 #include "tools/gn/deps_iterator.h" 24 #include "tools/gn/deps_iterator.h"
24 #include "tools/gn/filesystem_utils.h" 25 #include "tools/gn/filesystem_utils.h"
25 #include "tools/gn/settings.h" 26 #include "tools/gn/settings.h"
26 #include "tools/gn/source_file.h" 27 #include "tools/gn/source_file.h"
27 #include "tools/gn/target.h" 28 #include "tools/gn/target.h"
28 #include "tools/gn/value.h" 29 #include "tools/gn/value.h"
29 #include "tools/gn/variables.h" 30 #include "tools/gn/variables.h"
30 #include "tools/gn/xcode_object.h" 31 #include "tools/gn/xcode_object.h"
31 32
32 namespace { 33 namespace {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 break; 310 break;
310 311
311 default: 312 default:
312 break; 313 break;
313 } 314 }
314 } 315 }
315 316
316 projects_.push_back(std::move(main_project)); 317 projects_.push_back(std::move(main_project));
317 } 318 }
318 319
320 namespace {
321
322 template <typename T>
323 void SortAndRemoveDuplicates(std::vector<T>& vec) {
324 std::sort(vec.begin(), vec.end());
325 vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
326 }
327
328 template <typename T>
329 std::vector<T> IntersectSortedVectors(const std::vector<T>& vec,
330 const std::vector<T>& vec2) {
331 std::vector<T> intersection;
332 std::set_intersection(vec.begin(), vec.end(), vec2.begin(), vec2.end(),
333 std::back_inserter(intersection));
334 return intersection;
335 }
336
337 template <typename T>
338 std::vector<T> ExcludeSortedVectors(const std::vector<T>& from,
339 const std::vector<T>& what) {
340 std::vector<T> difference;
341 std::set_difference(from.begin(), from.end(), what.begin(), what.end(),
342 std::back_inserter(difference));
343 return difference;
344 }
345
346 void ExtractDialect(std::string& res,
347 const std::vector<std::string>& flags,
348 bool cc) {
349 for (const auto& flag : flags) {
350 if (res.empty() && flag.compare(0, 5, "-std=") == 0) {
351 res = flag;
352 }
353 if (!res.empty()) {
354 break;
355 }
356 }
357
358 // we're looking for c++ dialect, it must have + in name
359 if (cc && res.find('+') == std::string::npos)
360 res.clear();
361
362 // we're looking for c dialect, it must not have + in name
363 if (!cc && res.find('+') != std::string::npos)
364 res.clear();
365 }
366
367 void PrepareBuildAttributes(const std::vector<const Target*>& indexed_targets,
368 const SourceDir& root_build_dir,
369 std::map<SourceFile, std::string> & cflags,
370 PBXAttributes & attributes) {
371 std::vector<SourceDir> common_includes;
372 std::vector<std::string> common_defines;
373
374 for (const auto* target : indexed_targets) {
375 std::vector<SourceDir> target_includes;
376 std::vector<std::string> target_defines;
377
378 for (ConfigValuesIterator it(target); !it.done(); it.Next()) {
379 target_includes.insert(target_includes.end(),
380 it.cur().include_dirs().begin(),
381 it.cur().include_dirs().end());
382 target_defines.insert(target_defines.end(),
383 it.cur().defines().begin(),
384 it.cur().defines().end());
385 }
386 SortAndRemoveDuplicates(target_includes);
387 SortAndRemoveDuplicates(target_defines);
388
389 if (target == indexed_targets.front()) {
390 common_includes = std::move(target_includes);
391 common_defines = std::move(target_defines);
392 } else {
393 if (common_includes.empty() && common_defines.empty())
394 break;
395 common_includes = IntersectSortedVectors(common_includes,
396 target_includes);
397 common_defines = IntersectSortedVectors(common_defines,
398 target_defines);
399 }
400 }
401
402 for (const auto* target : indexed_targets) {
403 std::vector<SourceDir> target_includes;
404 std::vector<std::string> target_defines;
405
406 std::string target_dialect_c;
407 std::string target_dialect_cc;
408 std::string target_dialect_objc;
409 std::string target_dialect_objcc;
410
411 for (ConfigValuesIterator it(target); !it.done(); it.Next()) {
412 target_includes.insert(target_includes.end(),
413 it.cur().include_dirs().begin(),
414 it.cur().include_dirs().end());
415 target_defines.insert(target_defines.end(),
416 it.cur().defines().begin(),
417 it.cur().defines().end());
418
419 ExtractDialect(target_dialect_c, it.cur().cflags_c(), false);
420 ExtractDialect(target_dialect_c, it.cur().cflags(), false);
421 ExtractDialect(target_dialect_cc, it.cur().cflags_cc(), true);
422 ExtractDialect(target_dialect_cc, it.cur().cflags(), true);
423 ExtractDialect(target_dialect_objc, it.cur().cflags_objc(), false);
424 ExtractDialect(target_dialect_objc, it.cur().cflags(), false);
425 ExtractDialect(target_dialect_objcc, it.cur().cflags_objcc(), true);
426 ExtractDialect(target_dialect_objcc, it.cur().cflags(), true);
427 }
428 SortAndRemoveDuplicates(target_includes);
429 SortAndRemoveDuplicates(target_defines);
430
431 std::string target_cflags;
432
433 target_includes = ExcludeSortedVectors(target_includes, common_includes);
434 for (const auto& include : target_includes) {
435 std::string rebased = include.is_system_absolute()
436 ? include.value()
437 : RebasePath(include.value(), root_build_dir);
438 target_cflags += " -I";
439 target_cflags += rebased;
440 }
441
442 target_defines = ExcludeSortedVectors(target_defines, common_defines);
443 for (const auto& define : target_defines) {
444 target_cflags += " -D";
445 target_cflags += define;
446 }
447
448 if (!target_cflags.empty())
449 target_cflags = target_cflags.substr(1);
450
451 for (const SourceFile& source : target->sources()) {
452 std::string file_cflags = target_cflags;
453 std::string file_dialect;
454 const auto& ext = FindExtension(&source.value());
455 if (ext == "c")
456 file_dialect = target_dialect_c;
457 else if (ext == "cc" || ext == "cpp" || ext == "cxx")
458 file_dialect = target_dialect_cc;
459 else if (ext == "m")
460 file_dialect = target_dialect_objc;
461 else if (ext == "mm")
462 file_dialect = target_dialect_objcc;
463
464 if (!file_cflags.empty() && !file_dialect.empty())
465 file_cflags += " ";
466 file_cflags += file_dialect;
467
468 cflags[source] = file_cflags;
469 }
470 }
471
472 attributes["USE_HEADERMAP"] = "NO";
473
474 if (!common_includes.empty()) {
475 std::string includes;
476 for (const auto& include : common_includes) {
477 includes += include.is_system_absolute()
478 ? include.value()
479 : RebasePath(include.value(), root_build_dir);
480 includes += "\n";
481 }
482 attributes["HEADER_SEARCH_PATHS"] = includes;
483 }
484
485 if (!common_defines.empty()) {
486 std::string defines;
487 for (const auto& define : common_defines) {
488 defines += define;
489 defines += "\n";
490 }
491 attributes["GCC_PREPROCESSOR_DEFINITIONS"] = defines;
492 }
493 }
494
495 } // namespace
496
319 void XcodeWriter::CreateSourcesProject( 497 void XcodeWriter::CreateSourcesProject(
320 const std::vector<const Target*>& targets, 498 const std::vector<const Target*>& targets,
321 const SourceDir& root_build_dir, 499 const SourceDir& root_build_dir,
322 const PBXAttributes& attributes, 500 const PBXAttributes& attributes,
323 const std::string& source_path, 501 const std::string& source_path,
324 const std::string& config_name, 502 const std::string& config_name,
325 TargetOsType target_os) { 503 TargetOsType target_os) {
504
326 std::vector<SourceFile> sources; 505 std::vector<SourceFile> sources;
506 std::vector<const Target*> indexed_targets;
507
327 for (const Target* target : targets) { 508 for (const Target* target : targets) {
328 if (!target->settings()->is_default()) 509 if (!target->settings()->is_default())
329 continue; 510 continue;
330 511
331 for (const SourceFile& source : target->sources()) { 512 for (const SourceFile& source : target->sources()) {
332 if (source.is_system_absolute()) 513 if (source.is_system_absolute())
333 continue; 514 continue;
334 515
335 if (IsStringInOutputDir(root_build_dir, source.value())) 516 if (IsStringInOutputDir(root_build_dir, source.value()))
336 continue; 517 continue;
337 518
338 sources.push_back(source); 519 sources.push_back(source);
520
521 if (PBXProject::SourceFileShouldBeIndexed(source.value()) &&
522 (indexed_targets.empty() || indexed_targets.back() != target)) {
523 indexed_targets.push_back(target);
524 }
339 } 525 }
340 } 526 }
341 527
528 std::map<SourceFile, std::string> cflags;
529 PBXAttributes updated_attributes(attributes);
530 PrepareBuildAttributes(indexed_targets, root_build_dir, cflags,
531 updated_attributes);
532
342 std::unique_ptr<PBXProject> sources_for_indexing( 533 std::unique_ptr<PBXProject> sources_for_indexing(
343 new PBXProject("sources", config_name, source_path, attributes)); 534 new PBXProject("sources", config_name, source_path, updated_attributes));
344 535
345 // Sort sources to ensure determinisn of the project file generation and 536 // Sort sources to ensure determinisn of the project file generation and
346 // remove duplicate reference to the source files (can happen due to the 537 // remove duplicate reference to the source files (can happen due to the
347 // bundle_data targets). 538 // bundle_data targets).
348 std::sort(sources.begin(), sources.end()); 539 SortAndRemoveDuplicates(sources);
349 sources.erase(std::unique(sources.begin(), sources.end()), sources.end());
350 540
351 SourceDir source_dir("//"); 541 SourceDir source_dir("//");
352 for (const SourceFile& source : sources) { 542 for (const SourceFile& source : sources) {
353 std::string source_file = RebasePath(source.value(), source_dir); 543 std::string source_file = RebasePath(source.value(), source_dir);
354 sources_for_indexing->AddSourceFile(source_file); 544 sources_for_indexing->AddSourceFile(source_file, cflags[source]);
355 } 545 }
356 546
357 projects_.push_back(std::move(sources_for_indexing)); 547 projects_.push_back(std::move(sources_for_indexing));
358 } 548 }
359 549
360 bool XcodeWriter::WriteFiles(const BuildSettings* build_settings, Err* err) { 550 bool XcodeWriter::WriteFiles(const BuildSettings* build_settings, Err* err) {
361 for (const auto& project : projects_) { 551 for (const auto& project : projects_) {
362 if (!WriteProjectFile(build_settings, project.get(), err)) 552 if (!WriteProjectFile(build_settings, project.get(), err))
363 return false; 553 return false;
364 } 554 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 for (const auto& object : pair.second) { 615 for (const auto& object : pair.second) {
426 object->Print(out, 2); 616 object->Print(out, 2);
427 } 617 }
428 out << "/* End " << ToString(pair.first) << " section */\n"; 618 out << "/* End " << ToString(pair.first) << " section */\n";
429 } 619 }
430 620
431 out << "\t};\n" 621 out << "\t};\n"
432 << "\trootObject = " << project->Reference() << ";\n" 622 << "\trootObject = " << project->Reference() << ";\n"
433 << "}\n"; 623 << "}\n";
434 } 624 }
OLDNEW
« 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