C++: Changes internal C++ link() API to match Bazel

This is the new API introduced in https://github.com/bazelbuild/bazel/commit/0b03a28701d297c9ffe976c54580ceff32eec1b7. In this CL we keep the
SkylarkCallables separate so that the internal rules work with the old and the
new API to facilitate migration.

RELNOTES:none
PiperOrigin-RevId: 245023617
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
index f1cffd6..d486fd5 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
@@ -32,7 +32,6 @@
 import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainVariables;
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
-import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
 import com.google.devtools.build.lib.rules.cpp.CppSemantics;
 import com.google.devtools.build.lib.rules.cpp.FdoContext;
 import com.google.devtools.build.lib.rules.cpp.FeatureConfigurationForStarlark;
@@ -46,7 +45,6 @@
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.SkylarkList;
 import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
-import java.util.stream.Stream;
 
 /**
  * A module that contains Skylark utilities for C++ support.
@@ -68,24 +66,6 @@
         CcLinkingContext,
         CcToolchainVariables,
         CcToolchainConfigInfo> {
-  private static final ImmutableList<String> SUPPORTED_OUTPUT_TYPES =
-      ImmutableList.of("executable", "dynamic_library");
-
-  private enum Language {
-    CPP("c++"),
-    OBJC("objc"),
-    OBJCPP("objc++");
-
-    private final String representation;
-
-    Language(String representation) {
-      this.representation = representation;
-    }
-
-    public String getRepresentation() {
-      return representation;
-    }
-  }
 
   @Override
   public CppSemantics getSemantics() {
@@ -135,98 +115,6 @@
   }
 
   @Override
-  public Tuple<Object> createLinkingContextFromCompilationOutputs(
-      SkylarkActionFactory skylarkActionFactoryApi,
-      FeatureConfigurationForStarlark skylarkFeatureConfiguration,
-      CcToolchainProvider skylarkCcToolchainProvider,
-      CcCompilationOutputs compilationOutputs,
-      SkylarkList<String> userLinkFlags,
-      SkylarkList<CcLinkingContext> linkingContexts,
-      String name,
-      String language,
-      boolean alwayslink,
-      SkylarkList<Artifact> additionalInputs,
-      boolean disallowStaticLibraries,
-      boolean disallowDynamicLibraries,
-      Location location,
-      Environment environment,
-      StarlarkContext starlarkContext)
-      throws InterruptedException, EvalException {
-    CcCommon.checkLocationWhitelisted(
-        environment.getSemantics(),
-        location,
-        environment.getGlobals().getLabel().getPackageIdentifier().toString());
-    validateLanguage(location, language);
-    SkylarkActionFactory actions = skylarkActionFactoryApi;
-    CcToolchainProvider ccToolchainProvider = convertFromNoneable(skylarkCcToolchainProvider, null);
-    FeatureConfigurationForStarlark featureConfiguration =
-        convertFromNoneable(skylarkFeatureConfiguration, null);
-    Label label = getCallerLabel(location, environment, name);
-    FdoContext fdoContext = ccToolchainProvider.getFdoContext();
-    LinkTargetType staticLinkTargetType = null;
-    if (language.equals(Language.CPP.getRepresentation())) {
-      staticLinkTargetType = LinkTargetType.STATIC_LIBRARY;
-    } else if (language.equals(Language.OBJC.getRepresentation())
-        || language.equals(Language.OBJCPP.getRepresentation())) {
-      staticLinkTargetType = LinkTargetType.OBJC_ARCHIVE;
-    } else {
-      throw new IllegalStateException("Language is not valid.");
-    }
-    CcLinkingHelper helper =
-        new CcLinkingHelper(
-                actions.getActionConstructionContext().getRuleErrorConsumer(),
-                label,
-                actions.asActionRegistry(location, actions),
-                actions.getActionConstructionContext(),
-                BazelCppSemantics.INSTANCE,
-                featureConfiguration.getFeatureConfiguration(),
-                ccToolchainProvider,
-                fdoContext,
-                actions.getActionConstructionContext().getConfiguration(),
-                actions
-                    .getActionConstructionContext()
-                    .getConfiguration()
-                    .getFragment(CppConfiguration.class),
-                ((BazelStarlarkContext) starlarkContext).getSymbolGenerator())
-            .addNonCodeLinkerInputs(additionalInputs)
-            .setShouldCreateStaticLibraries(!disallowStaticLibraries)
-            .setShouldCreateDynamicLibrary(
-                !disallowDynamicLibraries
-                    && !featureConfiguration
-                        .getFeatureConfiguration()
-                        .isEnabled(CppRuleClasses.TARGETS_WINDOWS))
-            .setStaticLinkType(staticLinkTargetType)
-            .setDynamicLinkType(LinkTargetType.NODEPS_DYNAMIC_LIBRARY)
-            .addLinkopts(userLinkFlags);
-    try {
-      CcLinkingOutputs ccLinkingOutputs = CcLinkingOutputs.EMPTY;
-      ImmutableList<LibraryToLink> libraryToLink = ImmutableList.of();
-      if (!compilationOutputs.isEmpty()) {
-        ccLinkingOutputs = helper.link(compilationOutputs);
-        if (!ccLinkingOutputs.isEmpty()) {
-          libraryToLink =
-              ImmutableList.of(
-                  ccLinkingOutputs.getLibraryToLink().toBuilder()
-                      .setAlwayslink(alwayslink)
-                      .build());
-        }
-      }
-      CcLinkingContext linkingContext =
-          helper.buildCcLinkingContextFromLibrariesToLink(
-              libraryToLink, CcCompilationContext.EMPTY);
-      return Tuple.of(
-          CcLinkingContext.merge(
-              ImmutableList.<CcLinkingContext>builder()
-                  .add(linkingContext)
-                  .addAll(linkingContexts)
-                  .build()),
-          ccLinkingOutputs);
-    } catch (RuleErrorException e) {
-      throw new EvalException(location, e);
-    }
-  }
-
-  @Override
   public CcLinkingOutputs link(
       SkylarkActionFactory actions,
       FeatureConfigurationForStarlark skylarkFeatureConfiguration,
@@ -303,19 +191,4 @@
       throw new EvalException(location, e);
     }
   }
-
-  private void validateLanguage(Location location, String language) throws EvalException {
-    if (!Stream.of(Language.values())
-        .map(Language::getRepresentation)
-        .collect(ImmutableList.toImmutableList())
-        .contains(language)) {
-      throw new EvalException(location, "Language '" + language + "' is not supported");
-    }
-  }
-
-  private void validateOutputType(Location location, String outputType) throws EvalException {
-    if (!SUPPORTED_OUTPUT_TYPES.contains(outputType)) {
-      throw new EvalException(location, "Output type '" + outputType + "' is not supported");
-    }
-  }
 }
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 4496dac..5dd6edd 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
@@ -51,6 +51,8 @@
 import com.google.devtools.build.lib.rules.cpp.CcToolchainVariables.StringValueParser;
 import com.google.devtools.build.lib.rules.cpp.CppActionConfigs.CppPlatform;
 import com.google.devtools.build.lib.rules.cpp.LibraryToLink.CcLinkingContext;
+import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType;
+import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode;
 import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcInfoApi;
 import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcModuleApi;
 import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
@@ -70,6 +72,7 @@
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
@@ -91,6 +94,26 @@
         CcToolchainConfigInfo,
         CcCompilationOutputs> {
 
+  private static final ImmutableList<String> SUPPORTED_OUTPUT_TYPES =
+      ImmutableList.of("executable", "dynamic_library");
+
+  /** Enum for strings coming in from Starlark representing languages */
+  protected enum Language {
+    CPP("c++"),
+    OBJC("objc"),
+    OBJCPP("objc++");
+
+    private final String representation;
+
+    Language(String representation) {
+      this.representation = representation;
+    }
+
+    public String getRepresentation() {
+      return representation;
+    }
+  }
+
   public abstract CppSemantics getSemantics();
 
   @Override
@@ -1307,6 +1330,115 @@
     return CppHelper.useToolchainResolution(skylarkRuleContext.getRuleContext());
   }
 
+  @Override
+  public Tuple<Object> createLinkingContextFromCompilationOutputs(
+      SkylarkActionFactory skylarkActionFactoryApi,
+      FeatureConfigurationForStarlark skylarkFeatureConfiguration,
+      CcToolchainProvider skylarkCcToolchainProvider,
+      CcCompilationOutputs compilationOutputs,
+      SkylarkList<String> userLinkFlags,
+      SkylarkList<CcLinkingContext> linkingContexts,
+      String name,
+      String language,
+      boolean alwayslink,
+      SkylarkList<Artifact> additionalInputs,
+      boolean disallowStaticLibraries,
+      boolean disallowDynamicLibraries,
+      Object grepIncludes,
+      Location location,
+      Environment environment,
+      StarlarkContext starlarkContext)
+      throws InterruptedException, EvalException {
+    CcCommon.checkLocationWhitelisted(
+        environment.getSemantics(),
+        location,
+        environment.getGlobals().getLabel().getPackageIdentifier().toString());
+    validateLanguage(location, language);
+    SkylarkActionFactory actions = skylarkActionFactoryApi;
+    CcToolchainProvider ccToolchainProvider = convertFromNoneable(skylarkCcToolchainProvider, null);
+    FeatureConfigurationForStarlark featureConfiguration =
+        convertFromNoneable(skylarkFeatureConfiguration, null);
+    Label label = getCallerLabel(location, environment, name);
+    FdoContext fdoContext = ccToolchainProvider.getFdoContext();
+    LinkTargetType staticLinkTargetType = null;
+    if (language.equals(Language.CPP.getRepresentation())) {
+      staticLinkTargetType = LinkTargetType.STATIC_LIBRARY;
+    } else if (language.equals(Language.OBJC.getRepresentation())
+        || language.equals(Language.OBJCPP.getRepresentation())) {
+      staticLinkTargetType = LinkTargetType.OBJC_ARCHIVE;
+    } else {
+      throw new IllegalStateException("Language is not valid.");
+    }
+    CcLinkingHelper helper =
+        new CcLinkingHelper(
+                actions.getActionConstructionContext().getRuleErrorConsumer(),
+                label,
+                actions.asActionRegistry(location, actions),
+                actions.getActionConstructionContext(),
+                getSemantics(),
+                featureConfiguration.getFeatureConfiguration(),
+                ccToolchainProvider,
+                fdoContext,
+                actions.getActionConstructionContext().getConfiguration(),
+                actions
+                    .getActionConstructionContext()
+                    .getConfiguration()
+                    .getFragment(CppConfiguration.class),
+                ((BazelStarlarkContext) starlarkContext).getSymbolGenerator())
+            .setGrepIncludes(convertFromNoneable(grepIncludes, /* defaultValue= */ null))
+            .addNonCodeLinkerInputs(additionalInputs)
+            .setShouldCreateStaticLibraries(!disallowStaticLibraries)
+            .setShouldCreateDynamicLibrary(
+                !disallowDynamicLibraries
+                    && !featureConfiguration
+                        .getFeatureConfiguration()
+                        .isEnabled(CppRuleClasses.TARGETS_WINDOWS))
+            .setStaticLinkType(staticLinkTargetType)
+            .setDynamicLinkType(LinkTargetType.NODEPS_DYNAMIC_LIBRARY)
+            .addLinkopts(userLinkFlags);
+    try {
+      CcLinkingOutputs ccLinkingOutputs = CcLinkingOutputs.EMPTY;
+      ImmutableList<LibraryToLink> libraryToLink = ImmutableList.of();
+      if (!compilationOutputs.isEmpty()) {
+        ccLinkingOutputs = helper.link(compilationOutputs);
+        if (!ccLinkingOutputs.isEmpty()) {
+          libraryToLink =
+              ImmutableList.of(
+                  ccLinkingOutputs.getLibraryToLink().toBuilder()
+                      .setAlwayslink(alwayslink)
+                      .build());
+        }
+      }
+      CcLinkingContext linkingContext =
+          helper.buildCcLinkingContextFromLibrariesToLink(
+              libraryToLink, CcCompilationContext.EMPTY);
+      return Tuple.of(
+          CcLinkingContext.merge(
+              ImmutableList.<CcLinkingContext>builder()
+                  .add(linkingContext)
+                  .addAll(linkingContexts)
+                  .build()),
+          ccLinkingOutputs);
+    } catch (RuleErrorException e) {
+      throw new EvalException(location, e);
+    }
+  }
+
+  protected void validateLanguage(Location location, String language) throws EvalException {
+    if (!Arrays.stream(Language.values())
+        .map(Language::getRepresentation)
+        .collect(ImmutableList.toImmutableList())
+        .contains(language)) {
+      throw new EvalException(location, "Language '" + language + "' is not supported");
+    }
+  }
+
+  protected void validateOutputType(Location location, String outputType) throws EvalException {
+    if (!SUPPORTED_OUTPUT_TYPES.contains(outputType)) {
+      throw new EvalException(location, "Output type '" + outputType + "' is not supported");
+    }
+  }
+
   protected Label getCallerLabel(Location location, Environment environment, String name)
       throws EvalException {
     Label label;
@@ -1393,4 +1525,83 @@
       throw new EvalException(location, e);
     }
   }
+
+  protected CcLinkingOutputs link(
+      SkylarkActionFactory actions,
+      FeatureConfigurationForStarlark skylarkFeatureConfiguration,
+      CcToolchainProvider skylarkCcToolchainProvider,
+      CcCompilationOutputs compilationOutputs,
+      SkylarkList<String> userLinkFlags,
+      SkylarkList<CcLinkingContext> linkingContexts,
+      String name,
+      String language,
+      String outputType,
+      boolean linkDepsStatically,
+      SkylarkList<Artifact> additionalInputs,
+      Object grepIncludes,
+      Location location,
+      Environment environment,
+      StarlarkContext starlarkContext)
+      throws InterruptedException, EvalException {
+    CcCommon.checkLocationWhitelisted(
+        environment.getSemantics(),
+        location,
+        environment.getGlobals().getLabel().getPackageIdentifier().toString());
+    validateLanguage(location, language);
+    validateOutputType(location, outputType);
+    CcToolchainProvider ccToolchainProvider = convertFromNoneable(skylarkCcToolchainProvider, null);
+    FeatureConfigurationForStarlark featureConfiguration =
+        convertFromNoneable(skylarkFeatureConfiguration, null);
+    Label label = getCallerLabel(location, environment, name);
+    FdoContext fdoContext = ccToolchainProvider.getFdoContext();
+    LinkTargetType dynamicLinkTargetType = null;
+    if (language.equals(Language.CPP.getRepresentation())) {
+      if (outputType.equals("executable")) {
+        dynamicLinkTargetType = LinkTargetType.EXECUTABLE;
+      } else if (outputType.equals("dynamic_library")) {
+        dynamicLinkTargetType = LinkTargetType.DYNAMIC_LIBRARY;
+      }
+    } else if (language.equals(Language.OBJC.getRepresentation())
+        && outputType.equals("executable")) {
+      dynamicLinkTargetType = LinkTargetType.OBJC_EXECUTABLE;
+    } else if (language.equals(Language.OBJCPP.getRepresentation())
+        && outputType.equals("executable")) {
+      dynamicLinkTargetType = LinkTargetType.OBJCPP_EXECUTABLE;
+    } else {
+      throw new EvalException(
+          location, "Language '" + language + "' does not support " + outputType);
+    }
+
+    CcLinkingHelper helper =
+        new CcLinkingHelper(
+                actions.getActionConstructionContext().getRuleErrorConsumer(),
+                label,
+                actions.asActionRegistry(location, actions),
+                actions.getActionConstructionContext(),
+                getSemantics(),
+                featureConfiguration.getFeatureConfiguration(),
+                ccToolchainProvider,
+                fdoContext,
+                actions.getActionConstructionContext().getConfiguration(),
+                actions
+                    .getActionConstructionContext()
+                    .getConfiguration()
+                    .getFragment(CppConfiguration.class),
+                ((BazelStarlarkContext) starlarkContext).getSymbolGenerator())
+            .setGrepIncludes(convertFromNoneable(grepIncludes, /* defaultValue= */ null))
+            .setLinkingMode(linkDepsStatically ? LinkingMode.STATIC : LinkingMode.DYNAMIC)
+            .addNonCodeLinkerInputs(additionalInputs)
+            .setDynamicLinkType(dynamicLinkTargetType)
+            .addCcLinkingContexts(linkingContexts)
+            .addLinkopts(userLinkFlags);
+    try {
+      CcLinkingOutputs ccLinkingOutputs = CcLinkingOutputs.EMPTY;
+      if (!compilationOutputs.isEmpty()) {
+        ccLinkingOutputs = helper.link(compilationOutputs);
+      }
+      return ccLinkingOutputs;
+    } catch (RuleErrorException e) {
+      throw new EvalException(location, e);
+    }
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
index 7e72e20..62e0c25 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
@@ -312,120 +312,4 @@
       Environment environment,
       StarlarkContext starlarkContext)
       throws InterruptedException, EvalException;
-
-  @SkylarkCallable(
-      name = "create_linking_context_from_compilation_outputs",
-      doc =
-          "Should be used for creating library rules that can propagate information downstream in"
-              + " order to be linked later by a top level rule that does transitive linking to"
-              + " create an executable or dynamic library.",
-      useLocation = true,
-      useEnvironment = true,
-      useContext = true,
-      parameters = {
-        @Param(
-            name = "actions",
-            type = SkylarkActionFactoryApi.class,
-            positional = false,
-            named = true,
-            doc = "<code>actions</code> object."),
-        @Param(
-            name = "feature_configuration",
-            doc = "<code>feature_configuration</code> to be queried.",
-            positional = false,
-            named = true,
-            type = FeatureConfigurationApi.class),
-        @Param(
-            name = "cc_toolchain",
-            doc = "<code>CcToolchainInfo</code> provider to be used.",
-            positional = false,
-            named = true,
-            type = CcToolchainProviderApi.class),
-        @Param(
-            name = "compilation_outputs",
-            doc = "Compilation outputs containing object files to link.",
-            positional = false,
-            named = true,
-            type = CcCompilationOutputsApi.class),
-        @Param(
-            name = "user_link_flags",
-            doc = "Additional list of linking options.",
-            positional = false,
-            named = true,
-            defaultValue = "[]",
-            noneable = true,
-            type = SkylarkList.class),
-        @Param(
-            name = "linking_contexts",
-            doc =
-                "Libraries from dependencies. These libraries will be linked into the output "
-                    + "artifact of the link() call, be it a binary or a library.",
-            positional = false,
-            named = true,
-            noneable = true,
-            defaultValue = "[]",
-            type = SkylarkList.class),
-        @Param(
-            name = "name",
-            doc =
-                "This is used for naming the output artifacts of actions created by this "
-                    + "method.",
-            positional = false,
-            named = true,
-            type = String.class),
-        @Param(
-            name = "language",
-            doc = "Can be one of c++, objc or objc++.",
-            positional = false,
-            named = true,
-            noneable = true,
-            defaultValue = "'c++'",
-            type = String.class),
-        @Param(
-            name = "alwayslink",
-            doc = "Whether this library should always be linked.",
-            positional = false,
-            named = true,
-            noneable = true,
-            defaultValue = "False",
-            type = Boolean.class),
-        @Param(
-            name = "additional_inputs",
-            doc = "For additional inputs to the linking action, e.g.: linking scripts.",
-            positional = false,
-            named = true,
-            defaultValue = "[]",
-            type = SkylarkList.class),
-        @Param(
-            name = "disallow_static_libraries",
-            doc = "Whether static libraries should be created.",
-            positional = false,
-            named = true,
-            defaultValue = "False",
-            type = Boolean.class),
-        @Param(
-            name = "disallow_dynamic_library",
-            doc = "Whether a dynamic library should be created.",
-            positional = false,
-            named = true,
-            defaultValue = "False",
-            type = Boolean.class)
-      })
-  Tuple<Object> createLinkingContextFromCompilationOutputs(
-      SkylarkActionFactoryT skylarkActionFactoryApi,
-      FeatureConfigurationT skylarkFeatureConfiguration,
-      CcToolchainProviderT skylarkCcToolchainProvider,
-      CompilationOutputsT compilationOutputs,
-      SkylarkList<String> userLinkFlags,
-      SkylarkList<LinkingContextT> linkingContexts,
-      String name,
-      String language,
-      boolean alwayslink,
-      SkylarkList<FileT> additionalInputs,
-      boolean disallowStaticLibraries,
-      boolean disallowDynamicLibraries,
-      Location location,
-      Environment environment,
-      StarlarkContext bazelStarlarkContext)
-      throws InterruptedException, EvalException;
 }
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 a0925df..9109143 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
@@ -29,6 +29,7 @@
 import com.google.devtools.build.lib.syntax.Runtime.NoneType;
 import com.google.devtools.build.lib.syntax.SkylarkDict;
 import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
 import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
 
 /** Utilites related to C++ support. */
@@ -852,4 +853,128 @@
       Object builtinSysroot,
       Object ccTargetOs)
       throws EvalException;
+
+  @SkylarkCallable(
+      name = "create_linking_context_from_compilation_outputs",
+      doc =
+          "Should be used for creating library rules that can propagate information downstream in"
+              + " order to be linked later by a top level rule that does transitive linking to"
+              + " create an executable or dynamic library.",
+      useLocation = true,
+      useEnvironment = true,
+      useContext = true,
+      parameters = {
+        @Param(
+            name = "actions",
+            type = SkylarkActionFactoryApi.class,
+            positional = false,
+            named = true,
+            doc = "<code>actions</code> object."),
+        @Param(
+            name = "feature_configuration",
+            doc = "<code>feature_configuration</code> to be queried.",
+            positional = false,
+            named = true,
+            type = FeatureConfigurationApi.class),
+        @Param(
+            name = "cc_toolchain",
+            doc = "<code>CcToolchainInfo</code> provider to be used.",
+            positional = false,
+            named = true,
+            type = CcToolchainProviderApi.class),
+        @Param(
+            name = "compilation_outputs",
+            doc = "Compilation outputs containing object files to link.",
+            positional = false,
+            named = true,
+            type = CcCompilationOutputsApi.class),
+        @Param(
+            name = "user_link_flags",
+            doc = "Additional list of linking options.",
+            positional = false,
+            named = true,
+            defaultValue = "[]",
+            noneable = true,
+            type = SkylarkList.class),
+        @Param(
+            name = "linking_contexts",
+            doc =
+                "Libraries from dependencies. These libraries will be linked into the output "
+                    + "artifact of the link() call, be it a binary or a library.",
+            positional = false,
+            named = true,
+            noneable = true,
+            defaultValue = "[]",
+            type = SkylarkList.class),
+        @Param(
+            name = "name",
+            doc =
+                "This is used for naming the output artifacts of actions created by this "
+                    + "method.",
+            positional = false,
+            named = true,
+            type = String.class),
+        @Param(
+            name = "language",
+            doc = "Can be one of c++, objc or objc++.",
+            positional = false,
+            named = true,
+            noneable = true,
+            defaultValue = "'c++'",
+            type = String.class),
+        @Param(
+            name = "alwayslink",
+            doc = "Whether this library should always be linked.",
+            positional = false,
+            named = true,
+            noneable = true,
+            defaultValue = "False",
+            type = Boolean.class),
+        @Param(
+            name = "additional_inputs",
+            doc = "For additional inputs to the linking action, e.g.: linking scripts.",
+            positional = false,
+            named = true,
+            defaultValue = "[]",
+            type = SkylarkList.class),
+        @Param(
+            name = "disallow_static_libraries",
+            doc = "Whether static libraries should be created.",
+            positional = false,
+            named = true,
+            defaultValue = "False",
+            type = Boolean.class),
+        @Param(
+            name = "disallow_dynamic_library",
+            doc = "Whether a dynamic library should be created.",
+            positional = false,
+            named = true,
+            defaultValue = "False",
+            type = Boolean.class),
+        @Param(
+            name = "grep_includes",
+            positional = false,
+            named = true,
+            noneable = true,
+            defaultValue = "None",
+            allowedTypes = {@ParamType(type = FileApi.class), @ParamType(type = NoneType.class)}),
+      })
+  Tuple<Object> createLinkingContextFromCompilationOutputs(
+      SkylarkActionFactoryT skylarkActionFactoryApi,
+      FeatureConfigurationT skylarkFeatureConfiguration,
+      CcToolchainProviderT skylarkCcToolchainProvider,
+      CompilationOutputsT compilationOutputs,
+      SkylarkList<String> userLinkFlags,
+      SkylarkList<LinkingContextT> linkingContexts,
+      String name,
+      String language,
+      boolean alwayslink,
+      SkylarkList<FileT> additionalInputs,
+      boolean disallowStaticLibraries,
+      boolean disallowDynamicLibraries,
+      Object grepIncludes,
+      Location location,
+      Environment environment,
+      StarlarkContext bazelStarlarkContext)
+      throws InterruptedException, EvalException;
 }
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 db89916..ca2ea82 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
@@ -206,6 +206,7 @@
       SkylarkList<FileApi> nonCodeInputs,
       boolean disallowStaticLibraries,
       boolean disallowDynamicLibraries,
+      Object grepIncludes,
       Location location,
       Environment environment,
       StarlarkContext starlarkContext)