[xcode] Allow user to choose Xcode build system Xcode 10 introduced a new build system, and beta versions of Xcode 12 prints a warning if the legacy build system is used telling that it will be removed in a future version. Give the user an option to choose which build system to use. Bug: chromium:1094890 Change-Id: I681201cc5b1355f6139b96b20d74dc93a4545e63 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/9100 Commit-Queue: Sylvain Defresne <sdefresne@chromium.org> Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/docs/reference.md b/docs/reference.md index 7896bec..8d8d30e 100644 --- a/docs/reference.md +++ b/docs/reference.md
@@ -229,7 +229,7 @@ - "Found dependency" - "No dependency" - - "Found dependency (all) " + - "Found dependency (all)" In the first case, the lists returned in compile_targets and test_targets should be passed to ninja to build. In the second case, nothing was @@ -768,6 +768,12 @@ Override defaut Xcode project file name ("all"). The project file is written to the root build directory. + --xcode-build-system=<value> + Configure the build system to use for the Xcode project. Supported + values are (default to "legacy"): + "legacy" - Legacy Build system + "new" - New Build System + --ninja-executable=<string> Can be used to specify the ninja executable to use when building. @@ -1609,7 +1615,7 @@ bundle_resources_dir = bundle_contents_dir bundle_executable_dir = bundle_contents_dir - extra_attributes = { + xcode_extra_attributes = { ONLY_ACTIVE_ARCH = "YES" DEBUG_INFORMATION_FORMAT = "dwarf" }
diff --git a/src/gn/command_gen.cc b/src/gn/command_gen.cc index 8424165..0180cd1 100644 --- a/src/gn/command_gen.cc +++ b/src/gn/command_gen.cc
@@ -49,29 +49,15 @@ const char kSwitchRootTarget[] = "root-target"; const char kSwitchSln[] = "sln"; const char kSwitchXcodeProject[] = "xcode-project"; +const char kSwitchXcodeBuildSystem[] = "xcode-build-system"; +const char kSwitchXcodeBuildsystemValueLegacy[] = "legacy"; +const char kSwitchXcodeBuildsystemValueNew[] = "new"; const char kSwitchJsonFileName[] = "json-file-name"; const char kSwitchJsonIdeScript[] = "json-ide-script"; const char kSwitchJsonIdeScriptArgs[] = "json-ide-script-args"; const char kSwitchExportCompileCommands[] = "export-compile-commands"; const char kSwitchExportRustProject[] = "export-rust-project"; -// Extracts extra parameters for XcodeWriter from command-line flags. -XcodeWriter::Options XcodeWriterOptionsFromCommandLine( - const base::CommandLine& command_line) { - std::string project_name = - command_line.GetSwitchValueASCII(kSwitchXcodeProject); - if (project_name.empty()) - project_name = "all"; - - return { - std::move(project_name), - command_line.GetSwitchValueASCII(kSwitchRootTarget), - command_line.GetSwitchValueASCII(kSwitchNinjaExecutable), - command_line.GetSwitchValueASCII(kSwitchNinjaExtraArgs), - command_line.GetSwitchValueASCII(kSwitchFilters), - }; -} - // Collects Ninja rules for each toolchain. The lock protectes the rules. struct TargetWriteInfo { std::mutex lock; @@ -254,9 +240,34 @@ } return res; } else if (ide == kSwitchIdeValueXcode) { - bool res = XcodeWriter::RunAndWriteFiles( - build_settings, builder, - XcodeWriterOptionsFromCommandLine(*command_line), err); + XcodeWriter::Options options = { + command_line->GetSwitchValueASCII(kSwitchXcodeProject), + command_line->GetSwitchValueASCII(kSwitchRootTarget), + command_line->GetSwitchValueASCII(kSwitchNinjaExecutable), + command_line->GetSwitchValueASCII(kSwitchNinjaExtraArgs), + command_line->GetSwitchValueASCII(kSwitchFilters), + XcodeBuildSystem::kLegacy, + }; + + if (options.project_name.empty()) { + options.project_name = "all"; + } + + const std::string build_system = + command_line->GetSwitchValueASCII(kSwitchXcodeBuildSystem); + if (!build_system.empty()) { + if (build_system == kSwitchXcodeBuildsystemValueNew) { + options.build_system = XcodeBuildSystem::kNew; + } else if (build_system == kSwitchXcodeBuildsystemValueLegacy) { + options.build_system = XcodeBuildSystem::kLegacy; + } else { + *err = Err(Location(), "Unknown build system: " + build_system); + return false; + } + } + + bool res = + XcodeWriter::RunAndWriteFiles(build_settings, builder, options, err); if (res && !quiet) { OutputString("Generating Xcode projects took " + base::Int64ToString(timer.Elapsed().InMilliseconds()) + @@ -412,6 +423,12 @@ Override defaut Xcode project file name ("all"). The project file is written to the root build directory. + --xcode-build-system=<value> + Configure the build system to use for the Xcode project. Supported + values are (default to "legacy"): + "legacy" - Legacy Build system + "new" - New Build System + --ninja-executable=<string> Can be used to specify the ninja executable to use when building.
diff --git a/src/gn/functions_target.cc b/src/gn/functions_target.cc index 0864db5..f74cfa6 100644 --- a/src/gn/functions_target.cc +++ b/src/gn/functions_target.cc
@@ -443,7 +443,7 @@ bundle_resources_dir = bundle_contents_dir bundle_executable_dir = bundle_contents_dir - extra_attributes = { + xcode_extra_attributes = { ONLY_ACTIVE_ARCH = "YES" DEBUG_INFORMATION_FORMAT = "dwarf" }
diff --git a/src/gn/xcode_object.cc b/src/gn/xcode_object.cc index 7948b17..eb3bd64 100644 --- a/src/gn/xcode_object.cc +++ b/src/gn/xcode_object.cc
@@ -812,7 +812,6 @@ const std::string& shell_script) { PBXAttributes attributes; attributes["CLANG_ENABLE_OBJC_WEAK"] = "YES"; - attributes["CODE_SIGN_IDENTITY"] = ""; attributes["CODE_SIGNING_REQUIRED"] = "NO"; attributes["CONFIGURATION_BUILD_DIR"] = "."; attributes["PRODUCT_NAME"] = name; @@ -825,7 +824,6 @@ DCHECK(!target_for_indexing_); PBXAttributes attributes; attributes["CLANG_ENABLE_OBJC_WEAK"] = "YES"; - attributes["CODE_SIGN_IDENTITY"] = ""; attributes["CODE_SIGNING_REQUIRED"] = "NO"; attributes["EXECUTABLE_PREFIX"] = ""; attributes["HEADER_SEARCH_PATHS"] = sources_->path(); @@ -869,7 +867,6 @@ PBXAttributes attributes = extra_attributes; attributes["CLANG_ENABLE_OBJC_WEAK"] = "YES"; - attributes["CODE_SIGN_IDENTITY"] = ""; attributes["CODE_SIGNING_REQUIRED"] = "NO"; attributes["CONFIGURATION_BUILD_DIR"] = output_dir; attributes["PRODUCT_NAME"] = product_name;
diff --git a/src/gn/xcode_writer.cc b/src/gn/xcode_writer.cc index ee8c84d..0daf1c5 100644 --- a/src/gn/xcode_writer.cc +++ b/src/gn/xcode_writer.cc
@@ -373,6 +373,7 @@ // not set. Since the generated Xcode project is only used for debugging // and the source of truth for build settings is the .gn files themselves, // we can safely set them in the project as they won't be used by "ninja". + attributes["ALWAYS_SEARCH_USER_PATHS"] = "NO"; attributes["CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED"] = "YES"; attributes["CLANG_WARN__DUPLICATE_METHOD_MATCH"] = "YES"; attributes["CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING"] = "YES"; @@ -387,6 +388,7 @@ attributes["CLANG_WARN_NON_LITERAL_NULL_CONVERSION"] = "YES"; attributes["CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF"] = "YES"; attributes["CLANG_WARN_OBJC_LITERAL_CONVERSION"] = "YES"; + attributes["CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER"] = "YES"; attributes["CLANG_WARN_RANGE_LOOP_ANALYSIS"] = "YES"; attributes["CLANG_WARN_STRICT_PROTOTYPES"] = "YES"; attributes["CLANG_WARN_SUSPICIOUS_MOVE"] = "YES"; @@ -409,10 +411,11 @@ // Class representing the workspace embedded in an xcodeproj file used to // configure the build settings shared by all targets in the project (used -// to configure the build system to "Legacy build system"). +// to configure the build system). class XcodeWorkspace { public: - XcodeWorkspace(const BuildSettings* settings); + XcodeWorkspace(const BuildSettings* build_settings, + XcodeWriter::Options options); ~XcodeWorkspace(); XcodeWorkspace(const XcodeWorkspace&) = delete; @@ -429,10 +432,12 @@ bool WriteSettingsFile(const std::string& name, Err* err) const; const BuildSettings* build_settings_ = nullptr; + XcodeWriter::Options options_; }; -XcodeWorkspace::XcodeWorkspace(const BuildSettings* build_settings) - : build_settings_(build_settings) {} +XcodeWorkspace::XcodeWorkspace(const BuildSettings* build_settings, + XcodeWriter::Options options) + : build_settings_(build_settings), options_(options) {} XcodeWorkspace::~XcodeWorkspace() = default; @@ -475,10 +480,18 @@ << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " << "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" << "<plist version=\"1.0\">\n" - << "<dict>\n" - << "\t<key>BuildSystemType</key>\n" - << "\t<string>Original</string>\n" - << "</dict>\n" + << "<dict>\n"; + + switch (options_.build_system) { + case XcodeBuildSystem::kLegacy: + out << "\t<key>BuildSystemType</key>\n" + << "\t<string>Original</string>\n"; + break; + case XcodeBuildSystem::kNew: + break; + } + + out << "</dict>\n" << "</plist>\n"; return WriteFileIfChanged(build_settings_->GetFullPath(source_file), @@ -803,7 +816,7 @@ return false; } - XcodeWorkspace workspace(build_settings_); + XcodeWorkspace workspace(build_settings_, options_); return workspace.WriteWorkspace( project_.Name() + ".xcodeproj/project.xcworkspace", err); } @@ -909,6 +922,9 @@ PBXAttributes xcode_extra_attributes = target->bundle_data().xcode_extra_attributes(); + if (options_.build_system == XcodeBuildSystem::kLegacy) { + xcode_extra_attributes["CODE_SIGN_IDENTITY"] = ""; + } const std::string& target_output_name = RebasePath( target->bundle_data().GetBundleRootDirOutput(target->settings()).value(),
diff --git a/src/gn/xcode_writer.h b/src/gn/xcode_writer.h index 62f6ab5..b45b606 100644 --- a/src/gn/xcode_writer.h +++ b/src/gn/xcode_writer.h
@@ -17,6 +17,11 @@ class BuildSettings; class Err; +enum class XcodeBuildSystem { + kLegacy, + kNew, +}; + // Writes an Xcode workspace to build and debug code. class XcodeWriter { public: @@ -30,7 +35,7 @@ // try to build all defined targets. std::string root_target_name; - // Name of the ninja executable. Defaults to "ninja" is empty. + // Name of the ninja executable. Defaults to "ninja" if empty. std::string ninja_executable; // Extra parameters to pass to ninja. Deprecated. @@ -41,6 +46,10 @@ // (in the same way that the other filtering is done, source and header // files for those target will still be listed in the generated project). std::string dir_filters_string; + + // Control which version of the build system should be used for the + // generated Xcode project. + XcodeBuildSystem build_system = XcodeBuildSystem::kLegacy; }; // Writes an Xcode workspace with a single project file.