Expose cc_common.get_execution_requirements

This is used to control per-action execution requirements. Currently only used by objc and swift rules.

RELNOTES: None.
PiperOrigin-RevId: 250881803
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index f7a93a1..49970a7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -167,6 +167,13 @@
   }
 
   @Override
+  public SkylarkList<String> getExecutionRequirements(
+      FeatureConfigurationForStarlark featureConfiguration, String actionName) {
+    return SkylarkList.createImmutable(
+        featureConfiguration.getFeatureConfiguration().getToolRequirementsForAction(actionName));
+  }
+
+  @Override
   public boolean isEnabled(
       FeatureConfigurationForStarlark featureConfiguration, String featureName) {
     return featureConfiguration.getFeatureConfiguration().isEnabled(featureName);
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
index a56509a..4a15796 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
@@ -121,13 +121,38 @@
             name = "action_name",
             doc =
                 "Name of the action. Has to be one of the names in "
-                    + "@bazel_tools//tools/build_defs/cc:action_names.bzl.",
+                    + "@bazel_tools//tools/build_defs/cc:action_names.bzl "
+                    + "(https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/"
+                    + "action_names.bzl)",
             named = true,
             positional = false),
       })
   String getToolForAction(FeatureConfigurationT featureConfiguration, String actionName);
 
   @SkylarkCallable(
+      name = "get_execution_requirements",
+      doc = "Returns execution requirements for given action.",
+      parameters = {
+        @Param(
+            name = "feature_configuration",
+            doc = "Feature configuration to be queried.",
+            positional = false,
+            named = true,
+            type = FeatureConfigurationApi.class),
+        @Param(
+            name = "action_name",
+            doc =
+                "Name of the action. Has to be one of the names in "
+                    + "@bazel_tools//tools/build_defs/cc:action_names.bzl "
+                    + "(https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/"
+                    + "action_names.bzl)",
+            named = true,
+            positional = false),
+      })
+  SkylarkList<String> getExecutionRequirements(
+      FeatureConfigurationT featureConfiguration, String actionName);
+
+  @SkylarkCallable(
       name = "is_enabled",
       doc = "Returns True if given feature is enabled in the feature configuration.",
       parameters = {
@@ -181,7 +206,9 @@
             name = "action_name",
             doc =
                 "Name of the action. Has to be one of the names in "
-                    + "@bazel_tools//tools/build_defs/cc:action_names.bzl.",
+                    + "@bazel_tools//tools/build_defs/cc:action_names.bzl "
+                    + "(https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/"
+                    + "action_names.bzl)",
             named = true,
             positional = false),
         @Param(
@@ -211,7 +238,9 @@
             name = "action_name",
             doc =
                 "Name of the action. Has to be one of the names in "
-                    + "@bazel_tools//tools/build_defs/cc:action_names.bzl.",
+                    + "@bazel_tools//tools/build_defs/cc:action_names.bzl "
+                    + "(https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/"
+                    + "action_names.bzl)",
             named = true,
             positional = false),
         @Param(
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/BUILD b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/BUILD
index 51d7d30..8c0e01b 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/BUILD
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/BUILD
@@ -19,5 +19,6 @@
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp",
         "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi",
+        "//third_party:guava",
     ],
 )
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
index 7e7f008..24390b5 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.skydoc.fakebuildapi.cpp;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.skylarkbuildapi.FileApi;
 import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi;
@@ -76,6 +77,12 @@
   }
 
   @Override
+  public SkylarkList<String> getExecutionRequirements(
+      FeatureConfigurationApi featureConfiguration, String actionName) {
+    return SkylarkList.createImmutable(ImmutableList.of());
+  }
+
+  @Override
   public boolean isEnabled(FeatureConfigurationApi featureConfiguration, String featureName) {
     return false;
   }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/cc_toolchain_config.bzl b/src/test/java/com/google/devtools/build/lib/analysis/mock/cc_toolchain_config.bzl
index 9de5293..1d03db0 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/mock/cc_toolchain_config.bzl
+++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/cc_toolchain_config.bzl
@@ -98,6 +98,7 @@
     strip_debug_symbols = "strip_debug_symbols",
     disable_pbh = "disable_pbh",
     optional_cc_flags_feature = "optional_cc_flags_feature",
+    cpp_compile_with_requirements = "cpp_compile_with_requirements",
 )
 
 _disable_pbh_feature = feature(name = _FEATURE_NAMES.disable_pbh)
@@ -244,6 +245,8 @@
     ],
 )
 
+_cpp_compile_with_requirements = feature(name = _FEATURE_NAMES.cpp_compile_with_requirements)
+
 _header_module_codegen_feature = feature(
     name = _FEATURE_NAMES.header_module_codegen,
     implies = ["header_modules"],
@@ -972,6 +975,16 @@
     ],
 )
 
+_cpp_compile_with_requirements_action_config = action_config(
+    action_name = "yolo_action_with_requirements",
+    tools = [
+        tool(
+            path = "yolo_tool",
+            execution_requirements = ["requires-yolo"],
+        ),
+    ],
+)
+
 _foo_feature = feature(
     name = _FEATURE_NAMES.foo,
 )
@@ -1185,6 +1198,7 @@
     _FEATURE_NAMES.strip_debug_symbols: _strip_debug_symbols_feature,
     _FEATURE_NAMES.disable_pbh: _disable_pbh_feature,
     _FEATURE_NAMES.optional_cc_flags_feature: _optional_cc_flags_feature,
+    _FEATURE_NAMES.cpp_compile_with_requirements: _cpp_compile_with_requirements,
     "header_modules_feature_configuration": _header_modules_feature_configuration,
     "env_var_feature_configuration": _env_var_feature_configuration,
     "host_and_nonhost_configuration": _host_and_nonhost_configuration,
@@ -1315,10 +1329,13 @@
     features = [default_compile_flags_feature, default_link_flags_feature]
 
     should_add_multiple_tools_action_config = False
+    should_add_requirements = False
 
     for name in ctx.attr.feature_names:
         if name == _FEATURE_NAMES.change_tool:
             should_add_multiple_tools_action_config = True
+        if name == _FEATURE_NAMES.cpp_compile_with_requirements:
+            should_add_requirements = True
 
         features.extend(_get_features_for_configuration(name))
 
@@ -1345,6 +1362,9 @@
     if should_add_multiple_tools_action_config:
         action_configs.append(_multiple_tools_action_config)
 
+    if should_add_requirements:
+        action_configs.append(_cpp_compile_with_requirements_action_config)
+
     make_variables = [
         make_variable(name = name, value = value)
         for name, value in ctx.attr.make_variables.items()
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/MockCcSupport.java b/src/test/java/com/google/devtools/build/lib/packages/util/MockCcSupport.java
index e4d408c..cfe4730 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/MockCcSupport.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/MockCcSupport.java
@@ -112,6 +112,7 @@
       "major_version: 'foo'\nminor_version:' foo'\n" + emptyToolchainForCpu("k8");
 
   public static final String SIMPLE_COMPILE_FEATURE = "simple_compile_feature";
+  public static final String CPP_COMPILE_ACTION_WITH_REQUIREMENTS = "cpp_compile_with_requirements";
 
   public static String emptyToolchainForCpu(String cpu, String... append) {
     return Joiner.on("\n")
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
index ced6008..fc185c2 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
@@ -34,6 +34,7 @@
 import com.google.devtools.build.lib.packages.SkylarkProvider;
 import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.packages.util.Crosstool.CcToolchainConfig;
+import com.google.devtools.build.lib.packages.util.MockCcSupport;
 import com.google.devtools.build.lib.packages.util.ResourceLoader;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ActionConfig;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ArtifactNamePattern;
@@ -234,6 +235,48 @@
   }
 
   @Test
+  public void testExecutionRequirements() throws Exception {
+    AnalysisMock.get()
+        .ccSupport()
+        .setupCcToolchainConfig(
+            mockToolsConfig,
+            CcToolchainConfig.builder()
+                .withFeatures(MockCcSupport.CPP_COMPILE_ACTION_WITH_REQUIREMENTS));
+    scratch.file(
+        "a/BUILD",
+        "load(':rule.bzl', 'crule')",
+        "cc_toolchain_alias(name='alias')",
+        "crule(name='r')");
+
+    scratch.file(
+        "a/rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
+        "def _impl(ctx):",
+        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
+        "  feature_configuration = cc_common.configure_features(",
+        "    ctx = ctx,",
+        "    cc_toolchain = toolchain,",
+        "  )",
+        "  return [MyInfo(",
+        "    requirements = cc_common.get_execution_requirements(",
+        "        feature_configuration = feature_configuration,",
+        "        action_name = 'yolo_action_with_requirements'))]",
+        "crule = rule(",
+        "  _impl,",
+        "  attrs = { ",
+        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
+        "  },",
+        "  fragments = ['cpp'],",
+        ");");
+
+    ConfiguredTarget r = getConfiguredTarget("//a:r");
+    @SuppressWarnings("unchecked")
+    SkylarkList<String> requirements =
+        (SkylarkList<String>) getMyInfoFromTarget(r).getValue("requirements");
+    assertThat(requirements).containsExactly("requires-yolo");
+  }
+
+  @Test
   public void testFeatureConfigurationWithAdditionalEnabledFeature() throws Exception {
     AnalysisMock.get()
         .ccSupport()