Drop 32-bit architectures from builds with ios_mimimum_os > 11.0.

This change misses the corner case of builds which are entirely 32-bit (as opposed to mixed 32&64 bit) due to no legitimate place to report the error of such a build; execution will fail for such builds at the action level.

RELNOTES: None.
PiperOrigin-RevId: 169397354
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 6e9a2b6..44e20f5 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
@@ -73,7 +73,7 @@
   private static final ImmutableSet<String> IOS_SIMULATOR_TARGET_CPUS =
       ImmutableSet.of("ios_x86_64", "ios_i386");
   private static final ImmutableSet<String> IOS_DEVICE_TARGET_CPUS =
-          ImmutableSet.of("ios_armv6", "ios_arm64", "ios_armv7", "ios_armv7s");
+      ImmutableSet.of("ios_armv6", "ios_arm64", "ios_armv7", "ios_armv7s");
   private static final ImmutableSet<String> WATCHOS_SIMULATOR_TARGET_CPUS =
       ImmutableSet.of("watchos_i386");
   private static final ImmutableSet<String> WATCHOS_DEVICE_TARGET_CPUS =
@@ -85,6 +85,9 @@
   private static final ImmutableSet<String> MACOS_TARGET_CPUS =
       ImmutableSet.of("darwin_x86_64");
 
+  private static final ImmutableSet<String> BIT_32_TARGET_CPUS =
+      ImmutableSet.of("ios_i386", "ios_armv7", "ios_armv7s", "watchos_i386", "watchos_armv7k");
+
   private final String skylarkKey;
   private final String nameInPlist;
   private final PlatformType platformType;
@@ -165,11 +168,21 @@
   }
 
   /**
+   * Returns true if the platform for the given target cpu and platform type is a known 32-bit
+   * architecture.
+   *
+   * @param platformType platform type that the given cpu value is implied for
+   * @param arch architecture representation, such as 'arm64'
+   */
+  public static boolean is32Bit(PlatformType platformType, String arch) {
+    return BIT_32_TARGET_CPUS.contains(cpuStringForTarget(platformType, arch));
+  }
+
+  /**
    * Returns the platform cpu string for the given target cpu and platform type.
    *
    * @param platformType platform type that the given cpu value is implied for
    * @param arch architecture representation, such as 'arm64'
-   * @throws IllegalArgumentException if there is no valid apple platform for the given target cpu
    */
   public static String cpuStringForTarget(PlatformType platformType, String arch) {
     switch (platformType) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
index a80f350..6089544 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
@@ -37,6 +37,7 @@
 import com.google.devtools.build.lib.rules.apple.DottedVersion;
 import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PlatformRule;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * {@link SplitTransitionProvider} implementation for multi-architecture apple rules which can
@@ -172,17 +173,30 @@
       ConfigurationDistinguisher configurationDistinguisher;
       switch (platformType) {
         case IOS:
+          configurationDistinguisher = ConfigurationDistinguisher.APPLEBIN_IOS;
+          actualMinimumOsVersion =
+              minimumOsVersion.isPresent()
+                  ? minimumOsVersion.get()
+                  : buildOptions.get(AppleCommandLineOptions.class).iosMinimumOs;
           cpus = buildOptions.get(AppleCommandLineOptions.class).iosMultiCpus;
           if (cpus.isEmpty()) {
             cpus =
                 ImmutableList.of(
                     AppleConfiguration.iosCpuFromCpu(buildOptions.get(Options.class).cpu));
           }
-          configurationDistinguisher = ConfigurationDistinguisher.APPLEBIN_IOS;
-          actualMinimumOsVersion =
-              minimumOsVersion.isPresent()
-                  ? minimumOsVersion.get()
-                  : buildOptions.get(AppleCommandLineOptions.class).iosMinimumOs;
+          if (actualMinimumOsVersion != null
+              && actualMinimumOsVersion.compareTo(DottedVersion.fromString("11.0")) >= 0) {
+            List<String> non32BitCpus =
+                cpus.stream()
+                    .filter(cpu -> !ApplePlatform.is32Bit(PlatformType.IOS, cpu))
+                    .collect(Collectors.toList());
+            if (!non32BitCpus.isEmpty()) {
+              // TODO(b/65969900): Throw an exception here. Ideally, there would be an applicable
+              // exception to throw during configuration creation, but instead this validation needs
+              // to be deferred to later.
+              cpus = non32BitCpus;
+            }
+          }
           break;
         case WATCHOS:
           cpus = buildOptions.get(AppleCommandLineOptions.class).watchosCpus;
@@ -228,7 +242,7 @@
         // to decide architecture.
         // TODO(b/29355778, b/28403953): Use a crosstool for any apple rule. Deprecate ios_cpu.
         appleCommandLineOptions.iosCpu = cpu;
-  
+
         if (splitOptions.get(ObjcCommandLineOptions.class).enableCcDeps) {
           // Only set the (CC-compilation) CPU for dependencies if explicitly required by the user.
           // This helps users of the iOS rules who do not depend on CC rules as these CPU values
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java
index 2c4026e..1463894 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java
@@ -1104,7 +1104,7 @@
     Action lipoAction = actionProducingArtifact("//examples:bin", "_lipobin");
 
     Artifact armv7Binary = getSingleArchBinary(lipoAction, "armv7");
-    Artifact arm64Binary = getSingleArchBinary(lipoAction, "arm64");;
+    Artifact arm64Binary = getSingleArchBinary(lipoAction, "arm64");
 
     Artifact armv7ProtoLib =
         getFirstArtifactEndingWith(
@@ -1131,16 +1131,6 @@
         getGeneratingAction(arm64ProtoObjcSource).getInputs(), "two.proto")).isNotNull();
   }
 
-  private Artifact getSingleArchBinary(Action lipoAction, String arch) throws Exception {
-    for (Artifact archBinary : lipoAction.getInputs()) {
-      String execPath = archBinary.getExecPathString();
-      if (execPath.endsWith("bin_bin") && execPath.contains(arch)) {
-        return archBinary;
-      }
-    }
-    throw new AssertionError("Lipo action does not contain an input binary from arch " + arch);
-  }
-
   private SkylarkDict<String, SkylarkDict<String, Artifact>>
       generateAppleDebugOutputsSkylarkProviderMap() throws Exception {
     scratch.file("examples/rule/BUILD");
@@ -1470,4 +1460,9 @@
       assertThat(linkArgs).contains(expectedCommandLineFragment);
     }
   }
+
+  @Test
+  public void testDrops32BitArchitecture() throws Exception {
+    verifyDrops32BitArchitecture(RULE_TYPE);
+  }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleDynamicLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleDynamicLibraryTest.java
index 82b875a..169483a 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleDynamicLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleDynamicLibraryTest.java
@@ -203,4 +203,9 @@
   public void testMinimumOsDifferentTargets() throws Exception {
     checkMinimumOsDifferentTargets(RULE_TYPE, "_lipobin", "_bin");
   }
+
+  @Test
+  public void testDrops32BitArchitecture() throws Exception {
+    verifyDrops32BitArchitecture(RULE_TYPE);
+  }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryTest.java
index d76970a..a990858 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryTest.java
@@ -623,4 +623,4 @@
     assertThat(Artifact.toRootRelativePaths(action.getInputs())).doesNotContain(
         "package/libavoidCcLib.a");
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
index 8ac3587..b289808 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
@@ -111,6 +111,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import javax.annotation.Nullable;
 import org.junit.Before;
 
 /**
@@ -4981,6 +4982,29 @@
         .contains("-mios-simulator-version-min=9.0");
   }
 
+  protected void verifyDrops32BitArchitecture(RuleType ruleType) throws Exception {
+    scratch.file("libs/BUILD",
+        "objc_library(",
+        "    name = 'objc_lib',",
+        "    srcs = ['a.m'],",
+        ")");
+
+    ruleType.scratchTarget(
+        scratch,
+        "deps", "['//libs:objc_lib']",
+        "platform_type", "'ios'",
+        "minimum_os_version", "'11.0'"); // Does not support 32-bit architectures.
+
+    useConfiguration("--ios_multi_cpus=armv7,arm64,i386,x86_64");
+
+    Action lipoAction = actionProducingArtifact("//x:x", "_lipobin");
+
+    getSingleArchBinary(lipoAction, "arm64");
+    getSingleArchBinary(lipoAction, "x86_64");
+    assertThat(getSingleArchBinaryIfAvailable(lipoAction, "armv7")).isNull();
+    assertThat(getSingleArchBinaryIfAvailable(lipoAction, "i386")).isNull();
+  }
+
   /** Returns the full label string for labels within the main tools repository. */
   protected static String toolsRepoLabel(String label) {
     return TestConstants.TOOLS_REPOSITORY + label;
@@ -4992,4 +5016,25 @@
   protected static String toolsRepoExecPath(String execPath) {
     return TestConstants.TOOLS_REPOSITORY_PATH_PREFIX + execPath;
   }
+
+  @Nullable
+  protected Artifact getSingleArchBinaryIfAvailable(Action lipoAction, String arch)
+      throws Exception {
+    for (Artifact archBinary : lipoAction.getInputs()) {
+      String execPath = archBinary.getExecPathString();
+      if (execPath.endsWith("_bin") && execPath.contains(arch)) {
+        return archBinary;
+      }
+    }
+    return null;
+  }
+
+  protected Artifact getSingleArchBinary(Action lipoAction, String arch) throws Exception {
+    Artifact result = getSingleArchBinaryIfAvailable(lipoAction, arch);
+    if (result != null) {
+      return result;
+    } else {
+      throw new AssertionError("Lipo action does not contain an input binary from arch " + arch);
+    }
+  }
 }