[tvos] Add target_xcode_platform to set Xcode project
This adds target_xcode_platform that indicates the kind of iOS or
iOS-based platform so that Xcode project is configured with tvOS when
target_xcode_platform == "tvos".
Bug: chromium:391914246
Change-Id: Ie18c370e1f0de78573e50a716b7da550dfb51ffe
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/18840
Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
Reviewed-by: David Turner <digit@google.com>
diff --git a/docs/reference.md b/docs/reference.md
index 91521b7..93bc0af 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -163,6 +163,7 @@
* [script: [file name] Script file for actions.](#var_script)
* [sources: [file list] Source files for a target.](#var_sources)
* [swiftflags: [string list] Flags passed to the swift compiler.](#var_swiftflags)
+ * [target_xcode_platform: [string] The desired platform for the build.](#var_target_xcode_platform)
* [testonly: [boolean] Declares a target must only be used for testing.](#var_testonly)
* [transparent: [bool] True if the bundle is transparent.](#var_transparent)
* [visibility: [label list] A list of labels that can depend on a target.](#var_visibility)
@@ -6904,6 +6905,28 @@
"deps" list. If a dependency is public, they will be applied
recursively.
```
+### <a name="var_target_xcode_platform"></a>**target_xcode_platform**: The desired platform for the build. [Back to Top](#gn-reference)
+
+```
+ This value should be used to indicate the kind of iOS or iOS-based platform
+ that is being the desired platform for the primary object(s) of the build.
+
+ This should be set to the most specific value possible. So, "iphoneos" or
+ "tvos" should be used instead of "ios" where applicable, even though
+ iPhoneOS and tvOS are both iOS variants.
+
+ GN defaults this value to "iphoneos" and the configuration files should set
+ it to an appropriate value if it is not set via the command line or in the
+ args.gn file.
+
+ This value configures the base SDK and the targeted device families of the
+ generated Xcode project. only meaningful when generating with --ide=xcode.
+
+ Possible values
+
+ - "iphoneos"
+ - "tvos"
+```
### <a name="var_testonly"></a>**testonly**: Declares a target must only be used for testing. [Back to Top](#gn-reference)
```
diff --git a/src/gn/variables.cc b/src/gn/variables.cc
index d99fccf..561c2bc 100644
--- a/src/gn/variables.cc
+++ b/src/gn/variables.cc
@@ -2210,6 +2210,32 @@
}
)";
+const char kTargetXcodePlatform[] = "target_xcode_platform";
+const char kTargetXcodePlatform_HelpShort[] =
+ "target_xcode_platform: [string] The desired platform for the build.";
+const char kTargetXcodePlatform_Help[] =
+ R"(target_xcode_platform: The desired platform for the build.
+
+ This value should be used to indicate the kind of iOS or iOS-based platform
+ that is being the desired platform for the primary object(s) of the build.
+
+ This should be set to the most specific value possible. So, "iphoneos" or
+ "tvos" should be used instead of "ios" where applicable, even though
+ iPhoneOS and tvOS are both iOS variants.
+
+ GN defaults this value to "iphoneos" and the configuration files should set
+ it to an appropriate value if it is not set via the command line or in the
+ args.gn file.
+
+ This value configures the base SDK and the targeted device families of the
+ generated Xcode project. only meaningful when generating with --ide=xcode.
+
+ Possible values
+
+ - "iphoneos"
+ - "tvos"
+)";
+
const char kTestonly[] = "testonly";
const char kTestonly_HelpShort[] =
"testonly: [boolean] Declares a target must only be used for testing.";
@@ -2489,6 +2515,7 @@
INSERT_VARIABLE(Sources)
INSERT_VARIABLE(Swiftflags)
INSERT_VARIABLE(XcodeTestApplicationName)
+ INSERT_VARIABLE(TargetXcodePlatform)
INSERT_VARIABLE(Testonly)
INSERT_VARIABLE(Visibility)
INSERT_VARIABLE(WalkKeys)
diff --git a/src/gn/variables.h b/src/gn/variables.h
index b8a0d54..036b972 100644
--- a/src/gn/variables.h
+++ b/src/gn/variables.h
@@ -374,6 +374,10 @@
extern const char kXcodeExtraAttributes_HelpShort[];
extern const char kXcodeExtraAttributes_Help[];
+extern const char kTargetXcodePlatform[];
+extern const char kTargetXcodePlatform_HelpShort[];
+extern const char kTargetXcodePlatform_Help[];
+
extern const char kGenDeps[];
extern const char kGenDeps_HelpShort[];
extern const char kGenDeps_Help[];
diff --git a/src/gn/xcode_writer.cc b/src/gn/xcode_writer.cc
index ea84a3d..62945ad 100644
--- a/src/gn/xcode_writer.cc
+++ b/src/gn/xcode_writer.cc
@@ -48,6 +48,11 @@
WRITER_TARGET_OS_MACOS,
};
+enum TargetPlatformType {
+ WRITER_TARGET_PLATFORM_IPHONEOS,
+ WRITER_TARGET_PLATFORM_TVOS,
+};
+
const char* kXCTestFileSuffixes[] = {
"egtest.m", "egtest.mm", "egtest.swift", "xctest.m", "xctest.mm",
"xctest.swift", "UITests.m", "UITests.mm", "UITests.swift",
@@ -81,6 +86,25 @@
return WRITER_TARGET_OS_MACOS;
}
+std::optional<TargetPlatformType> GetTargetPlatform(const Args& args,
+ const ParseNode* node,
+ Err* err) {
+ const Value* target_platform_value =
+ args.GetArgOverride(variables::kTargetXcodePlatform);
+ if (target_platform_value) {
+ if (target_platform_value->type() == Value::STRING) {
+ if (target_platform_value->string_value() == "tvos")
+ return WRITER_TARGET_PLATFORM_TVOS;
+ if (target_platform_value->string_value() != "iphoneos") {
+ *err = Err(node, "Unknown target_platform value",
+ target_platform_value->string_value());
+ return std::nullopt;
+ }
+ }
+ }
+ return WRITER_TARGET_PLATFORM_IPHONEOS;
+}
+
std::string GetBuildScript(const std::string& target_name,
const std::string& ninja_executable,
const std::string& build_dir,
@@ -396,14 +420,26 @@
// Returns the default attributes for the project from settings.
PBXAttributes ProjectAttributesFromBuildSettings(
- const BuildSettings* build_settings) {
+ const BuildSettings* build_settings,
+ const ParseNode* node,
+ Err* err) {
const TargetOsType target_os = GetTargetOs(build_settings->build_args());
PBXAttributes attributes;
switch (target_os) {
- case WRITER_TARGET_OS_IOS:
- attributes["SDKROOT"] = "iphoneos";
- attributes["TARGETED_DEVICE_FAMILY"] = "1,2";
+ case WRITER_TARGET_OS_IOS: {
+ const std::optional<TargetPlatformType> target_platform =
+ GetTargetPlatform(build_settings->build_args(), node, err);
+ if (!target_platform)
+ return {};
+ if (*target_platform == WRITER_TARGET_PLATFORM_TVOS) {
+ attributes["SDKROOT"] = "appletvos";
+ attributes["TARGETED_DEVICE_FAMILY"] = "3";
+ } else {
+ attributes["SDKROOT"] = "iphoneos";
+ attributes["TARGETED_DEVICE_FAMILY"] = "1,2";
+ }
+ }
break;
case WRITER_TARGET_OS_MACOS:
attributes["SDKROOT"] = "macosx";
@@ -677,7 +713,9 @@
project_(options.project_name,
ConfigListFromOptions(options.configurations),
SourcePathFromBuildSettings(build_settings),
- ProjectAttributesFromBuildSettings(build_settings)) {}
+ ProjectAttributesFromBuildSettings(build_settings,
+ /*node=*/nullptr,
+ /*err=*/nullptr)) {}
XcodeProject::~XcodeProject() = default;