Support rest of objc-specific features in CcCommon.configureFeatures

This requires migrating the dead_strip and generate_linkmap options to
CppOptions / CppConfiguration.  For now, we keep the corresponding
information in ObjcConfiguration, but we can eventually delete them.

PiperOrigin-RevId: 455232743
Change-Id: I68cdeafe24064a7d3c56e6c090063179d1635c42
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
index fbbe426..3bd0033 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
@@ -155,6 +155,15 @@
           .addAll(ALL_OTHER_ACTIONS)
           .build();
 
+  public static final ImmutableSet<String> OBJC_ACTIONS =
+      ImmutableSet.of(
+          CppActionNames.OBJC_COMPILE,
+          CppActionNames.OBJCPP_COMPILE,
+          CppActionNames.OBJC_ARCHIVE,
+          CppActionNames.OBJC_FULLY_LINK,
+          CppActionNames.OBJC_EXECUTABLE,
+          CppActionNames.OBJCPP_EXECUTABLE);
+
   /** An enum for the list of supported languages. */
   public enum Language {
     CPP("c++"),
@@ -1031,6 +1040,12 @@
 
     if (language == Language.OBJC || language == Language.OBJCPP) {
       allRequestedFeaturesBuilder.add(CppRuleClasses.LANG_OBJC);
+      if (cppConfiguration.objcGenerateLinkmap()) {
+        allRequestedFeaturesBuilder.add(CppRuleClasses.GENERATE_LINKMAP_FEATURE_NAME);
+      }
+      if (cppConfiguration.objcShouldStripBinary()) {
+        allRequestedFeaturesBuilder.add(CppRuleClasses.DEAD_STRIP_FEATURE_NAME);
+      }
     }
 
     ImmutableSet<String> allUnsupportedFeatures = unsupportedFeaturesBuilder.build();
@@ -1059,6 +1074,10 @@
             .addAll(toolchain.getFeatures().getDefaultFeaturesAndActionConfigs())
             .addAll(cppConfiguration.getAppleBitcodeMode().getFeatureNames());
 
+    if (language == Language.OBJC || language == Language.OBJCPP) {
+      allFeatures.addAll(OBJC_ACTIONS);
+    }
+
     if (!cppConfiguration.dontEnableHostNonhost()) {
       if (toolchain.isToolConfiguration()) {
         allFeatures.add("host");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index 28e5ab8..54acf28 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -867,6 +867,15 @@
     return cppOptions.objcGenerateDotdFiles;
   }
 
+  @Override
+  public boolean objcGenerateLinkmap() {
+    return cppOptions.objcGenerateLinkmap;
+  }
+
+  public boolean objcEnableBinaryStripping() {
+    return cppOptions.objcEnableBinaryStripping;
+  }
+
   @StarlarkMethod(
       name = "experimental_cc_interface_deps",
       documented = false,
@@ -975,4 +984,9 @@
   public AppleBitcodeMode getAppleBitcodeMode() {
     return appleBitcodeMode;
   }
+
+  @Override
+  public boolean objcShouldStripBinary() {
+    return objcEnableBinaryStripping() && getCompilationMode() == CompilationMode.OPT;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
index 3ee77fc..ea3bd3e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
@@ -958,6 +958,25 @@
   public boolean appleEnableAutoDsymDbg;
 
   @Option(
+      name = "objc_generate_linkmap",
+      defaultValue = "false",
+      documentationCategory = OptionDocumentationCategory.OUTPUT_SELECTION,
+      effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+      help = "Specifies whether to generate a linkmap file.")
+  public boolean objcGenerateLinkmap;
+
+  @Option(
+      name = "objc_enable_binary_stripping",
+      defaultValue = "false",
+      documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
+      effectTags = {OptionEffectTag.ACTION_COMMAND_LINES},
+      help =
+          "Whether to perform symbol and dead-code strippings on linked binaries. Binary "
+              + "strippings will be performed if both this flag and --compilation_mode=opt are "
+              + "specified.")
+  public boolean objcEnableBinaryStripping;
+
+  @Option(
       name = "experimental_starlark_cc_import",
       defaultValue = "false",
       documentationCategory = OptionDocumentationCategory.BUILD_TIME_OPTIMIZATION,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
index b495290..b0a0797 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
@@ -470,6 +470,12 @@
    */
   public static final String NO_GENERATE_DEBUG_SYMBOLS_FEATURE_NAME = "no_generate_debug_symbols";
 
+  /** A feature to indicate whether to generate linkmap. For Apple platform only. */
+  public static final String GENERATE_LINKMAP_FEATURE_NAME = "generate_linkmap";
+
+  /** A feature to indicate whether to do linker deadstrip. For Apple platform only. */
+  public static final String DEAD_STRIP_FEATURE_NAME = "dead_strip";
+
   /**
    * A feature which indicates that this target is a test (rather than a binary). This can be used
    * to select test-only options.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
index a4ada31..57edf94 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
@@ -142,19 +142,6 @@
   private static final Predicate<Artifact> ALWAYS_LINKED_CC_LIBRARY =
       input -> LINK_LIBRARY_FILETYPES.matches(input.getFilename());
 
-  private static final String DEAD_STRIP_FEATURE_NAME = "dead_strip";
-
-  private static final String GENERATE_LINKMAP_FEATURE_NAME = "generate_linkmap";
-
-  private static final ImmutableList<String> OBJC_ACTIONS =
-      ImmutableList.of(
-          "objc-compile",
-          "objc++-compile",
-          "objc-archive",
-          "objc-fully-link",
-          "objc-executable",
-          "objc++-executable");
-
   /** Returns the location of the xcrunwrapper tool. */
   public static final FilesToRunProvider xcrunwrapper(RuleContext ruleContext) {
     return ruleContext.getExecutablePrerequisite("$xcrunwrapper");
@@ -171,34 +158,6 @@
           .withSourceAttributes("srcs", "non_arc_srcs", "hdrs")
           .withDependencyAttributes("deps", "data", "binary", "xctest_app");
 
-  private FeatureConfiguration getFeatureConfiguration(
-      RuleContext ruleContext,
-      CcToolchainProvider ccToolchain,
-      BuildConfigurationValue configuration,
-      CppSemantics cppSemantics) {
-    ImmutableSet.Builder<String> activatedCrosstoolSelectables =
-        ImmutableSet.<String>builder().addAll(ruleContext.getFeatures()).addAll(OBJC_ACTIONS);
-
-    if (configuration.getFragment(ObjcConfiguration.class).shouldStripBinary()) {
-      activatedCrosstoolSelectables.add(DEAD_STRIP_FEATURE_NAME);
-    }
-    if (configuration.getFragment(ObjcConfiguration.class).generateLinkmap()) {
-      activatedCrosstoolSelectables.add(GENERATE_LINKMAP_FEATURE_NAME);
-    }
-
-    ImmutableSet.Builder<String> disabledFeatures =
-        ImmutableSet.<String>builder().addAll(ruleContext.getDisabledFeatures());
-
-    return CcCommon.configureFeaturesOrReportRuleError(
-        ruleContext,
-        buildConfiguration,
-        activatedCrosstoolSelectables.build(),
-        disabledFeatures.build(),
-        Language.OBJC,
-        ccToolchain,
-        cppSemantics);
-  }
-
   /** Iterable wrapper providing strong type safety for arguments to binary linking. */
   static final class ExtraLinkArgs extends IterableWrapper<String> {
     ExtraLinkArgs(String... args) {
@@ -562,7 +521,14 @@
 
     Artifact binaryToLink = getBinaryToLink();
     FeatureConfiguration featureConfiguration =
-        getFeatureConfiguration(ruleContext, toolchain, buildConfiguration, cppSemantics);
+        CcCommon.configureFeaturesOrReportRuleError(
+            ruleContext,
+            buildConfiguration,
+            ruleContext.getFeatures(),
+            ruleContext.getDisabledFeatures(),
+            Language.OBJC,
+            toolchain,
+            cppSemantics);
 
     Label binaryLabel = null;
     try {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
index 8eab27e..b6248ec 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
@@ -89,15 +89,6 @@
   public String tvosSimulatorDevice;
 
   @Option(
-    name = "objc_generate_linkmap",
-    defaultValue = "false",
-    documentationCategory = OptionDocumentationCategory.OUTPUT_SELECTION,
-    effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
-    help = "Specifies whether to generate a linkmap file."
-  )
-  public boolean generateLinkmap;
-
-  @Option(
     name = "ios_memleaks",
     defaultValue = "false",
     documentationCategory = OptionDocumentationCategory.TESTING,
@@ -129,17 +120,6 @@
   public List<String> fastbuildOptions;
 
   @Option(
-      name = "objc_enable_binary_stripping",
-      defaultValue = "false",
-      documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
-      effectTags = {OptionEffectTag.ACTION_COMMAND_LINES},
-      help =
-          "Whether to perform symbol and dead-code strippings on linked binaries. Binary "
-              + "strippings will be performed if both this flag and --compilation_mode=opt are "
-              + "specified.")
-  public boolean enableBinaryStripping;
-
-  @Option(
     name = "ios_signing_cert_name",
     defaultValue = "null",
     documentationCategory = OptionDocumentationCategory.SIGNING,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
index 62ed921..2d6cba4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
@@ -53,11 +53,14 @@
   private final String watchosSimulatorDevice;
   private final DottedVersion tvosSimulatorVersion;
   private final String tvosSimulatorDevice;
+  // TODO(b/236152224): Delete after Starlark uses are migrated to CppConfiguration.
   private final boolean generateLinkmap;
   private final boolean runMemleaks;
+  // TODO(b/236152224): Delete after Starlark uses are migrated to CppConfiguration.
   private final ImmutableList<String> copts;
   private final CompilationMode compilationMode;
   private final ImmutableList<String> fastbuildOptions;
+  // TODO(b/236152224): Delete after Starlark uses are migrated to CppConfiguration.
   private final boolean enableBinaryStripping;
   @Nullable private final String signingCertName;
   private final boolean debugWithGlibcxx;
@@ -75,12 +78,12 @@
     this.watchosSimulatorVersion = DottedVersion.maybeUnwrap(objcOptions.watchosSimulatorVersion);
     this.tvosSimulatorDevice = objcOptions.tvosSimulatorDevice;
     this.tvosSimulatorVersion = DottedVersion.maybeUnwrap(objcOptions.tvosSimulatorVersion);
-    this.generateLinkmap = objcOptions.generateLinkmap;
+    this.generateLinkmap = cppOptions.objcGenerateLinkmap;
     this.runMemleaks = objcOptions.runMemleaks;
     this.copts = ImmutableList.copyOf(cppOptions.objcoptList);
     this.compilationMode = Preconditions.checkNotNull(options.compilationMode, "compilationMode");
     this.fastbuildOptions = ImmutableList.copyOf(objcOptions.fastbuildOptions);
-    this.enableBinaryStripping = objcOptions.enableBinaryStripping;
+    this.enableBinaryStripping = cppOptions.objcEnableBinaryStripping;
     this.signingCertName = objcOptions.iosSigningCertName;
     this.debugWithGlibcxx = objcOptions.debugWithGlibcxx;
     this.deviceDebugEntitlements = objcOptions.deviceDebugEntitlements;
diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CppConfigurationApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CppConfigurationApi.java
index 35ee83f..4bbc9cb 100644
--- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CppConfigurationApi.java
+++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CppConfigurationApi.java
@@ -164,6 +164,18 @@
       structField = true)
   boolean appleGenerateDsym();
 
+  @StarlarkMethod(
+      name = "objc_generate_linkmap",
+      doc = "(Apple-only) Whether to generate linkmap artifacts.",
+      structField = true)
+  boolean objcGenerateLinkmap();
+
+  @StarlarkMethod(
+      name = "objc_should_strip_binary",
+      structField = true,
+      doc = "(Apple-only) whether to perform symbol and dead-code strippings on linked binaries.")
+  boolean objcShouldStripBinary();
+
   @StarlarkMethod(name = "strip_opts", documented = false, useStarlarkThread = true)
   Sequence<String> getStripOptsStarlark(StarlarkThread thread) throws EvalException;
 
diff --git a/src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl b/src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl
index 85e4308..4993484 100644
--- a/src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl
+++ b/src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl
@@ -111,23 +111,10 @@
     )
 
 def _build_feature_configuration(common_variables, for_swift_module_map, support_parse_headers):
-    activated_crosstool_selectables = []
     ctx = common_variables.ctx
-    OBJC_ACTIONS = [
-        "objc-compile",
-        "objc++-compile",
-        "objc-archive",
-        "objc-fully-link",
-        "objc-executable",
-        "objc++-executable",
-    ]
-    activated_crosstool_selectables.extend(ctx.features)
-    activated_crosstool_selectables.extend(OBJC_ACTIONS)
-    if common_variables.objc_config.should_strip_binary:
-        activated_crosstool_selectables.append("dead_strip")
 
-    if common_variables.objc_config.generate_linkmap:
-        activated_crosstool_selectables.append("generate_linkmap")
+    enabled_features = []
+    enabled_features.extend(ctx.features)
 
     disabled_features = []
     disabled_features.extend(ctx.disabled_features)
@@ -141,18 +128,18 @@
         disabled_features.append("parse_headers")
 
     if for_swift_module_map:
-        activated_crosstool_selectables.append("module_maps")
-        activated_crosstool_selectables.append("compile_all_modules")
-        activated_crosstool_selectables.append("only_doth_headers_in_module_maps")
-        activated_crosstool_selectables.append("exclude_private_headers_in_module_maps")
-        activated_crosstool_selectables.append("module_map_without_extern_module")
+        enabled_features.append("module_maps")
+        enabled_features.append("compile_all_modules")
+        enabled_features.append("only_doth_headers_in_module_maps")
+        enabled_features.append("exclude_private_headers_in_module_maps")
+        enabled_features.append("module_map_without_extern_module")
         disabled_features.append("generate_submodules")
 
     return cc_common.configure_features(
         ctx = common_variables.ctx,
         cc_toolchain = common_variables.toolchain,
         language = "objc",
-        requested_features = activated_crosstool_selectables,
+        requested_features = enabled_features,
         unsupported_features = disabled_features,
     )