[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.