From 7acfc0728d69bea36698c382d843b929b63143b5 Mon Sep 17 00:00:00 2001
From: Liu Liu <i@liuliu.me>
Date: Tue, 3 Jan 2023 14:41:38 -0500
Subject: [PATCH 1/3] WIP: Mac Catalyst support for bazel / rules_swift /
 rules_apple

This is the first of a few PRs to add Mac Catalyst support for Bazel. I
have an app that can be successfully built with a few manual patches to
the bundle (proper actool usage, different bundle Info.plist, codesign,
and notarization). But overall, it can be successful built with an app
that passes macOS AppStore review / automatic checks.

This is WIP, as I need to migrate a few manual input flags into
crosstool section, and need advices from Bazel maintainers.
---
 .../build/lib/rules/apple/ApplePlatform.java  |   2 +-
 .../apple/ApplePlatformApi.java               |   1 +
 .../apple/ApplePlatformTypeApi.java           |   1 +
 tools/osx/crosstool/BUILD.toolchains          |   8 ++
 tools/osx/crosstool/cc_toolchain_config.bzl   | 113 +++++++++++++-----
 tools/osx/crosstool/osx_archs.bzl             |   2 +
 6 files changed, 93 insertions(+), 34 deletions(-)

diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java b/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java
index a050bbd4fcfd5f..70bb1e79d2bfd8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java
@@ -55,7 +55,7 @@ public enum ApplePlatform implements ApplePlatformApi {
   private static final ImmutableSet<String> TVOS_DEVICE_TARGET_CPUS =
       ImmutableSet.of("tvos_arm64");
   private static final ImmutableSet<String> CATALYST_TARGET_CPUS =
-      ImmutableSet.of("catalyst_x86_64");
+      ImmutableSet.of("catalyst_x86_64", "catalyst_arm64");
   // "darwin" is included because that's currently the default when on macOS, and
   // migrating it would be a breaking change more details:
   // https://github.com/bazelbuild/bazel/pull/7062
diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ApplePlatformApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ApplePlatformApi.java
index 15908e12a70e42..cb1b7cb7d101c9 100644
--- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ApplePlatformApi.java
+++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ApplePlatformApi.java
@@ -33,6 +33,7 @@
             + " href='apple_common.html#platform'>apple_common.platform</a> struct:<br><ul>"
             + "<li><code>apple_common.platform.ios_device</code></li>"
             + "<li><code>apple_common.platform.ios_simulator</code></li>"
+            + "<li><code>apple_common.platform.catalyst</code></li>"
             + "<li><code>apple_common.platform.macos</code></li>"
             + "<li><code>apple_common.platform.tvos_device</code></li>"
             + "<li><code>apple_common.platform.tvos_simulator</code></li>"
diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ApplePlatformTypeApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ApplePlatformTypeApi.java
index e110ad94c78198..1aed9a3b7bad31 100644
--- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ApplePlatformTypeApi.java
+++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ApplePlatformTypeApi.java
@@ -30,6 +30,7 @@
             + " href='apple_common.html#platform_type'>apple_common.platform_type</a>:<br><ul>"
             + "<li><code>apple_common.platform_type.ios</code></li>"
             + "<li><code>apple_common.platform_type.macos</code></li>"
+            + "<li><code>apple_common.platform_type.catalyst</code></li>"
             + "<li><code>apple_common.platform_type.tvos</code></li>"
             + "<li><code>apple_common.platform_type.watchos</code></li></ul><p>Likewise, the"
             + " platform type of an existing platform value can be retrieved using its"
diff --git a/tools/osx/crosstool/BUILD.toolchains b/tools/osx/crosstool/BUILD.toolchains
index 866c6f5ee73314..1e2fe0d3939a94 100644
--- a/tools/osx/crosstool/BUILD.toolchains
+++ b/tools/osx/crosstool/BUILD.toolchains
@@ -23,6 +23,14 @@ OSX_TOOLS_CONSTRAINTS = {
         "@platforms//os:osx",
         "@platforms//cpu:x86_64",
     ],
+    "catalyst_arm64": [
+        "@platforms//os:osx",
+        "@platforms//cpu:arm64",
+    ],
+    "catalyst_x86_64": [
+        "@platforms//os:osx",
+        "@platforms//cpu:x86_64",
+    ],
     "ios_arm64": [
         "@platforms//os:ios",
         "@platforms//cpu:arm64",
diff --git a/tools/osx/crosstool/cc_toolchain_config.bzl b/tools/osx/crosstool/cc_toolchain_config.bzl
index 66a45f5389c774..6a5b6b8f8e0644 100644
--- a/tools/osx/crosstool/cc_toolchain_config.bzl
+++ b/tools/osx/crosstool/cc_toolchain_config.bzl
@@ -97,6 +97,10 @@ def _impl(ctx):
         target_system_name = "x86_64-apple-tvos{}-simulator".format(target_os_version)
     elif (ctx.attr.cpu == "watchos_x86_64"):
         target_system_name = "x86_64-apple-watchos{}-simulator".format(target_os_version)
+    elif (ctx.attr.cpu == "catalyst_x86_64"):
+        target_system_name = "x86_64-apple-ios{}-macabi".format(target_os_version)
+    elif (ctx.attr.cpu == "catalyst_arm64"):
+        target_system_name = "arm64-apple-ios{}-macabi".format(target_os_version)
     else:
         fail("Unreachable")
 
@@ -692,7 +696,9 @@ def _impl(ctx):
         ctx.attr.cpu == "watchos_armv7k" or
         ctx.attr.cpu == "watchos_i386" or
         ctx.attr.cpu == "watchos_x86_64" or
-        ctx.attr.cpu == "watchos_arm64"):
+        ctx.attr.cpu == "watchos_arm64" or
+        ctx.attr.cpu == "catalyst_x86_64" or
+        ctx.attr.cpu == "catalyst_arm64"):
         apply_default_compiler_flags_feature = feature(
             name = "apply_default_compiler_flags",
             flag_sets = [
@@ -941,7 +947,9 @@ def _impl(ctx):
         ctx.attr.cpu == "watchos_armv7k" or
         ctx.attr.cpu == "watchos_i386" or
         ctx.attr.cpu == "watchos_x86_64" or
-        ctx.attr.cpu == "watchos_arm64"):
+        ctx.attr.cpu == "watchos_arm64" or
+        ctx.attr.cpu == "catalyst_x86_64" or
+        ctx.attr.cpu == "catalyst_arm64"):
         contains_objc_source_feature = feature(
             name = "contains_objc_source",
             flag_sets = [
@@ -1260,35 +1268,68 @@ def _impl(ctx):
 
     coverage_feature = feature(name = "coverage")
 
-    include_system_dirs_feature = feature(
-        name = "include_system_dirs",
-        flag_sets = [
-            flag_set(
-                actions = [
-                    ACTION_NAMES.c_compile,
-                    ACTION_NAMES.cpp_compile,
-                    ACTION_NAMES.cpp_module_compile,
-                    ACTION_NAMES.cpp_header_parsing,
-                    ACTION_NAMES.objc_compile,
-                    ACTION_NAMES.objcpp_compile,
-                    "objc-executable",
-                    "objc++-executable",
-                    ACTION_NAMES.assemble,
-                    ACTION_NAMES.preprocess_assemble,
-                ],
-                flag_groups = [
-                    flag_group(
-                        flags = [
-                            "-isysroot",
-                            "%{sdk_dir}",
-                            "-F%{sdk_framework_dir}",
-                            "-F%{platform_developer_framework_dir}",
-                        ],
-                    ),
-                ],
-            ),
-        ],
-    )
+    if (ctx.attr.cpu == "catalyst_x86_64" or
+        ctx.attr.cpu == "catalyst_arm64"):
+        include_system_dirs_feature = feature(
+            name = "include_system_dirs",
+            flag_sets = [
+                flag_set(
+                    actions = [
+                        ACTION_NAMES.c_compile,
+                        ACTION_NAMES.cpp_compile,
+                        ACTION_NAMES.cpp_module_compile,
+                        ACTION_NAMES.cpp_header_parsing,
+                        ACTION_NAMES.objc_compile,
+                        ACTION_NAMES.objcpp_compile,
+                        "objc-executable",
+                        "objc++-executable",
+                        ACTION_NAMES.assemble,
+                        ACTION_NAMES.preprocess_assemble,
+                    ],
+                    flag_groups = [
+                        flag_group(
+                            flags = [
+                                "-isysroot",
+                                "%{sdk_dir}",
+                                "-F%{sdk_framework_dir}",
+                                "-F%{platform_developer_framework_dir}",
+                                "-F%{sdk_dir}/System/iOSSupport/System/Library/Frameworks",
+                            ],
+                        ),
+                    ],
+                ),
+            ],
+        )
+    else:
+        include_system_dirs_feature = feature(
+            name = "include_system_dirs",
+            flag_sets = [
+                flag_set(
+                    actions = [
+                        ACTION_NAMES.c_compile,
+                        ACTION_NAMES.cpp_compile,
+                        ACTION_NAMES.cpp_module_compile,
+                        ACTION_NAMES.cpp_header_parsing,
+                        ACTION_NAMES.objc_compile,
+                        ACTION_NAMES.objcpp_compile,
+                        "objc-executable",
+                        "objc++-executable",
+                        ACTION_NAMES.assemble,
+                        ACTION_NAMES.preprocess_assemble,
+                    ],
+                    flag_groups = [
+                        flag_group(
+                            flags = [
+                                "-isysroot",
+                                "%{sdk_dir}",
+                                "-F%{sdk_framework_dir}",
+                                "-F%{platform_developer_framework_dir}",
+                            ],
+                        ),
+                    ],
+                ),
+            ],
+        )
 
     input_param_flags_feature = feature(
         name = "input_param_flags",
@@ -1542,7 +1583,9 @@ def _impl(ctx):
         ctx.attr.cpu == "watchos_armv7k" or
         ctx.attr.cpu == "watchos_i386" or
         ctx.attr.cpu == "watchos_x86_64" or
-        ctx.attr.cpu == "watchos_arm64"):
+        ctx.attr.cpu == "watchos_arm64" or
+        ctx.attr.cpu == "catalyst_x86_64" or
+        ctx.attr.cpu == "catalyst_arm64"):
         apply_implicit_frameworks_feature = feature(
             name = "apply_implicit_frameworks",
             flag_sets = [
@@ -2395,6 +2438,8 @@ def _impl(ctx):
         ctx.attr.cpu == "tvos_arm64" or
         ctx.attr.cpu == "watchos_arm64_32" or
         ctx.attr.cpu == "watchos_armv7k" or
+        ctx.attr.cpu == "catalyst_x86_64" or
+        ctx.attr.cpu == "catalyst_arm64" or
         ctx.attr.cpu == "darwin_x86_64" or
         ctx.attr.cpu == "darwin_arm64" or
         ctx.attr.cpu == "darwin_arm64e"):
@@ -2652,7 +2697,9 @@ def _impl(ctx):
         ctx.attr.cpu == "watchos_armv7k" or
         ctx.attr.cpu == "watchos_i386" or
         ctx.attr.cpu == "watchos_x86_64" or
-        ctx.attr.cpu == "watchos_arm64"):
+        ctx.attr.cpu == "watchos_arm64" or
+        ctx.attr.cpu == "catalyst_x86_64" or
+        ctx.attr.cpu == "catalyst_arm64"):
         features = [
             fastbuild_feature,
             no_legacy_features_feature,
diff --git a/tools/osx/crosstool/osx_archs.bzl b/tools/osx/crosstool/osx_archs.bzl
index aeb82ac6953cb7..d0921b682b2edc 100644
--- a/tools/osx/crosstool/osx_archs.bzl
+++ b/tools/osx/crosstool/osx_archs.bzl
@@ -32,6 +32,8 @@ OSX_TOOLS_ARCHS = [
     "ios_armv7",
     "ios_arm64",
     "ios_arm64e",
+    "catalyst_x86_64",
+    "catalyst_arm64",
     "watchos_armv7k",
     "watchos_arm64_32",
     "tvos_arm64",

From bd862e38b3ab6093d39f6705070cdb2ae07d26b7 Mon Sep 17 00:00:00 2001
From: Liu Liu <i@liuliu.me>
Date: Tue, 3 Jan 2023 17:27:10 -0500
Subject: [PATCH 2/3] Add ios_support_link_flag_feature.

---
 tools/osx/crosstool/cc_toolchain_config.bzl | 27 +++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/tools/osx/crosstool/cc_toolchain_config.bzl b/tools/osx/crosstool/cc_toolchain_config.bzl
index 6a5b6b8f8e0644..99abaa150e866b 100644
--- a/tools/osx/crosstool/cc_toolchain_config.bzl
+++ b/tools/osx/crosstool/cc_toolchain_config.bzl
@@ -1106,6 +1106,32 @@ def _impl(ctx):
             ],
         )
 
+    if (ctx.attr.cpu == "catalyst_x86_64" or
+        ctx.attr.cpu == "catalyst_arm64"):
+        ios_support_link_flags_feature = feature(
+            name = "ios_support_link_flags",
+            enabled = True,
+            flag_sets = [
+                flag_set(
+                    actions = all_link_actions +
+                              ["objc-executable", "objc++-executable"],
+                    flag_groups = [
+                        flag_group(
+                            flags = [
+                                "-frameworkwithsysroot",
+                                "System/iOS/System/Library/Frameworks",
+                                "-L%{sdk_dir}/System/iOSSupport/usr/lib",
+                            ],
+                        ),
+                    ],
+                ),
+            ],
+        )
+    else:
+        ios_support_link_flags_feature = feature(
+            name = "ios_support_link_flags"
+        )
+
     no_deduplicate_feature = feature(
         name = "no_deduplicate",
         enabled = True,
@@ -2758,6 +2784,7 @@ def _impl(ctx):
             relative_ast_path_feature,
             user_link_flags_feature,
             default_link_flags_feature,
+            ios_support_link_flags_feature,
             no_deduplicate_feature,
             dead_strip_feature,
             cpp_linker_flags_feature,

From 5d1532914c1409b0ae8edba1baf714e069670781 Mon Sep 17 00:00:00 2001
From: Liu Liu <i@liuliu.me>
Date: Sun, 12 Mar 2023 17:37:06 -0400
Subject: [PATCH 3/3] Fix minor parameter issue.

---
 tools/osx/crosstool/cc_toolchain_config.bzl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/osx/crosstool/cc_toolchain_config.bzl b/tools/osx/crosstool/cc_toolchain_config.bzl
index 99abaa150e866b..d81a5def5d68bc 100644
--- a/tools/osx/crosstool/cc_toolchain_config.bzl
+++ b/tools/osx/crosstool/cc_toolchain_config.bzl
@@ -1118,7 +1118,7 @@ def _impl(ctx):
                     flag_groups = [
                         flag_group(
                             flags = [
-                                "-frameworkwithsysroot",
+                                "-iframeworkwithsysroot",
                                 "System/iOS/System/Library/Frameworks",
                                 "-L%{sdk_dir}/System/iOSSupport/usr/lib",
                             ],