// Copyright 2016 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.rules.cpp;

import static java.nio.charset.StandardCharsets.ISO_8859_1;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ParameterFile;
import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.devtools.build.lib.collect.ImmutableIterable;
import com.google.devtools.build.lib.collect.IterablesChain;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.LibraryToLinkValue;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.SequenceBuilder;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.VariablesExtension;
import com.google.devtools.build.lib.rules.cpp.CppLinkAction.Context;
import com.google.devtools.build.lib.rules.cpp.CppLinkAction.LinkArtifactFactory;
import com.google.devtools.build.lib.rules.cpp.Link.LinkStaticness;
import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType;
import com.google.devtools.build.lib.rules.cpp.Link.Staticness;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/** Builder class to construct {@link CppLinkAction}s. */
public class CppLinkActionBuilder {

  /** A build variable for entries in the linker runtime search path (usually set by -rpath flag) */
  public static final String RUNTIME_LIBRARY_SEARCH_DIRECTORIES_VARIABLE =
      "runtime_library_search_directories";

  public static final String LIBRARY_SEARCH_DIRECTORIES_VARIABLE = "library_search_directories";

  /** A build variable for flags providing files to link as inputs in the linker invocation */
  public static final String LIBRARIES_TO_LINK_VARIABLE = "libraries_to_link";

  /**
   * A build variable for thinlto param file produced by thinlto-indexing action and consumed by
   * normal linking actions.
   */
  public static final String THINLTO_PARAM_FILE_VARIABLE = "thinlto_param_file";

  public static final String DEF_FILE_PATH_VARIABLE = "def_file_path";

  /**
   * A build variable to let thinlto know where it should write linker flags when indexing.
   */
  public static final String THINLTO_INDEXING_PARAM_FILE_VARIABLE = "thinlto_indexing_param_file";

  public static final String THINLTO_PREFIX_REPLACE_VARIABLE = "thinlto_prefix_replace";

  /**
   * A build variable to let the LTO indexing step know how to map from the minimized bitcode file
   * to the full bitcode file used by the LTO Backends.
   */
  public static final String THINLTO_OBJECT_SUFFIX_REPLACE_VARIABLE =
      "thinlto_object_suffix_replace";

  /**
   * A build variable for linker param file created by Bazel to overcome the command line length
   * limit.
   */
  public static final String LINKER_PARAM_FILE_VARIABLE = "linker_param_file";

  /** A build variable for the execpath of the output of the linker. */
  public static final String OUTPUT_EXECPATH_VARIABLE = "output_execpath";

  /** A build variable setting if interface library should be generated. */
  public static final String GENERATE_INTERFACE_LIBRARY_VARIABLE = "generate_interface_library";

  /** A build variable for the path to the interface library builder tool. */
  public static final String INTERFACE_LIBRARY_BUILDER_VARIABLE = "interface_library_builder_path";

  /** A build variable for the input for the interface library builder tool. */
  public static final String INTERFACE_LIBRARY_INPUT_VARIABLE = "interface_library_input_path";

  /** A build variable for the path where to generate interface library using the builder tool. */
  public static final String INTERFACE_LIBRARY_OUTPUT_VARIABLE = "interface_library_output_path";

  /** A build variable for hard-coded linker flags currently only known by bazel. */
  public static final String LEGACY_LINK_FLAGS_VARIABLE = "legacy_link_flags";

  /** A build variable giving a path to which to write symbol counts. */
  public static final String SYMBOL_COUNTS_OUTPUT_VARIABLE = "symbol_counts_output";

  /** A build variable giving linkstamp paths. */
  public static final String LINKSTAMP_PATHS_VARIABLE = "linkstamp_paths";

  /** A build variable whose presence indicates that PIC code should be generated. */
  public static final String FORCE_PIC_VARIABLE = "force_pic";

  /** A build variable whose presence indicates that the debug symbols should be stripped. */
  public static final String STRIP_DEBUG_SYMBOLS_VARIABLE = "strip_debug_symbols";

  @Deprecated
  public static final String IS_CC_TEST_LINK_ACTION_VARIABLE = "is_cc_test_link_action";

  /** A build variable whose presence indicates that this action is a cc_test linking action. */
  public static final String IS_CC_TEST_VARIABLE = "is_cc_test";

  /**
   * Temporary build variable for migrating osx crosstool.
   * TODO(b/37271982): Remove after blaze with ar action_config release
   */
  public static final String USES_ACTION_CONFIG_FOR_AR_VARIABLE =
      "uses_action_configs_for_cc_archiving";

  /**
   *  A build variable whose presence indicates that files were compiled with fission (debug
   *  info is in .dwo files instead of .o files and linker needs to know).
   */
  public static final String IS_USING_FISSION_VARIABLE = "is_using_fission";

  @Deprecated
  public static final String IS_NOT_CC_TEST_LINK_ACTION_VARIABLE = "is_not_cc_test_link_action";

  // Builder-only
  // Null when invoked from tests (e.g. via createTestBuilder).
  @Nullable private final RuleContext ruleContext;
  private final AnalysisEnvironment analysisEnvironment;
  private final Artifact output;
  private final CppSemantics unusedCppSemantics;
  @Nullable private String mnemonic;

  // can be null for CppLinkAction.createTestBuilder()
  @Nullable private final CcToolchainProvider toolchain;
  private final FdoSupportProvider fdoSupport;
  private Artifact interfaceOutput;
  private Artifact symbolCounts;
  private PathFragment runtimeSolibDir;
  protected final BuildConfiguration configuration;
  private final CppConfiguration cppConfiguration;
  private FeatureConfiguration featureConfiguration;

  // Morally equivalent with {@link Context}, except these are mutable.
  // Keep these in sync with {@link Context}.
  private final Set<LinkerInput> objectFiles = new LinkedHashSet<>();
  private final Set<Artifact> nonCodeInputs = new LinkedHashSet<>();
  private final NestedSetBuilder<LibraryToLink> libraries = NestedSetBuilder.linkOrder();
  private NestedSet<Artifact> crosstoolInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
  private Artifact runtimeMiddleman;
  private ArtifactCategory runtimeType = null;
  private NestedSet<Artifact> runtimeInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
  private final NestedSetBuilder<Artifact> compilationInputs = NestedSetBuilder.stableOrder();
  private final Set<Artifact> linkstamps = new LinkedHashSet<>();
  private ImmutableList<String> additionalLinkstampDefines = ImmutableList.of();
  private final List<String> linkopts = new ArrayList<>();
  private LinkTargetType linkType = LinkTargetType.STATIC_LIBRARY;
  private LinkStaticness linkStaticness = LinkStaticness.FULLY_STATIC;
  private String libraryIdentifier = null;
  private ImmutableMap<Artifact, Artifact> ltoBitcodeFiles;
  private Artifact defFile;

  private boolean fake;
  private boolean isNativeDeps;
  private boolean useTestOnlyFlags;
  private boolean wholeArchive;
  private LinkArtifactFactory linkArtifactFactory = CppLinkAction.DEFAULT_ARTIFACT_FACTORY;

  private boolean isLtoIndexing = false;
  private boolean usePicForLtoBackendActions = false;
  private Iterable<LtoBackendArtifacts> allLtoArtifacts = null;
  
  private final List<VariablesExtension> variablesExtensions = new ArrayList<>();
  private final NestedSetBuilder<Artifact> linkActionInputs = NestedSetBuilder.stableOrder();
  private final ImmutableList.Builder<Artifact> linkActionOutputs = ImmutableList.builder();

  /**
   * Creates a builder that builds {@link CppLinkAction} instances.
   *
   * @param ruleContext the rule that owns the action
   * @param output the output artifact
   * @param toolchain the C++ toolchain provider
   * @param fdoSupport the C++ FDO optimization support
   * @param cppSemantics to be used for linkstamp compiles
   */
  public CppLinkActionBuilder(
      RuleContext ruleContext,
      Artifact output,
      CcToolchainProvider toolchain,
      FdoSupportProvider fdoSupport,
      FeatureConfiguration featureConfiguration,
      CppSemantics cppSemantics) {
    this(
        ruleContext,
        output,
        ruleContext.getConfiguration(),
        ruleContext.getAnalysisEnvironment(),
        toolchain,
        fdoSupport,
        featureConfiguration,
        cppSemantics);
  }

  /**
   * Creates a builder that builds {@link CppLinkAction} instances.
   *
   * @param ruleContext the rule that owns the action
   * @param output the output artifact
   * @param configuration build configuration
   * @param toolchain C++ toolchain provider
   * @param fdoSupport the C++ FDO optimization support
   * @param cppSemantics to be used for linkstamp compiles
   */
  public CppLinkActionBuilder(
      RuleContext ruleContext,
      Artifact output,
      BuildConfiguration configuration,
      CcToolchainProvider toolchain,
      FdoSupportProvider fdoSupport,
      FeatureConfiguration featureConfiguration,
      CppSemantics cppSemantics) {
    this(
        ruleContext,
        output,
        configuration,
        ruleContext.getAnalysisEnvironment(),
        toolchain,
        fdoSupport,
        featureConfiguration,
        cppSemantics);
  }

  /**
   * Creates a builder that builds {@link CppLinkAction}s.
   *
   * @param ruleContext the rule that owns the action
   * @param output the output artifact
   * @param configuration the configuration used to determine the tool chain and the default link
   *     options
   * @param toolchain the C++ toolchain provider
   * @param fdoSupport the C++ FDO optimization support
   * @param cppSemantics to be used for linkstamp compiles
   */
  private CppLinkActionBuilder(
      @Nullable RuleContext ruleContext,
      Artifact output,
      BuildConfiguration configuration,
      AnalysisEnvironment analysisEnvironment,
      CcToolchainProvider toolchain,
      FdoSupportProvider fdoSupport,
      FeatureConfiguration featureConfiguration,
      CppSemantics cppSemantics) {
    this.ruleContext = ruleContext;
    this.analysisEnvironment = Preconditions.checkNotNull(analysisEnvironment);
    this.output = Preconditions.checkNotNull(output);
    this.configuration = Preconditions.checkNotNull(configuration);
    this.cppConfiguration = configuration.getFragment(CppConfiguration.class);
    this.toolchain = toolchain;
    this.fdoSupport = fdoSupport;
    if (toolchain.supportsEmbeddedRuntimes() && toolchain != null) {
      runtimeSolibDir = toolchain.getDynamicRuntimeSolibDir();
    }
    this.featureConfiguration = featureConfiguration;
    this.unusedCppSemantics = Preconditions.checkNotNull(cppSemantics);
  }

  /**
   * Given a Context, creates a Builder that builds {@link CppLinkAction}s. Note well: Keep the
   * Builder->Context and Context->Builder transforms consistent!
   *
   * @param ruleContext the rule that owns the action
   * @param output the output artifact
   * @param linkContext an immutable CppLinkAction.Context from the original builder
   * @param configuration build configuration
   * @param toolchain the C++ toolchain provider
   * @param fdoSupport the C++ FDO optimization support
   * @param cppSemantics to be used for linkstamp compiles
   */
  public CppLinkActionBuilder(
      RuleContext ruleContext,
      Artifact output,
      Context linkContext,
      BuildConfiguration configuration,
      CcToolchainProvider toolchain,
      FdoSupportProvider fdoSupport,
      FeatureConfiguration featureConfiguration,
      CppSemantics cppSemantics) {
    // These Builder-only fields get set in the constructor:
    //   ruleContext, analysisEnvironment, outputPath, configuration, runtimeSolibDir
    this(
        ruleContext,
        output,
        configuration,
        ruleContext.getAnalysisEnvironment(),
        toolchain,
        fdoSupport,
        featureConfiguration,
        cppSemantics);
    Preconditions.checkNotNull(linkContext);

    // All linkContext fields should be transferred to this Builder.
    this.objectFiles.addAll(linkContext.objectFiles);
    this.nonCodeInputs.addAll(linkContext.nonCodeInputs);
    this.libraries.addTransitive(linkContext.libraries);
    this.crosstoolInputs = linkContext.crosstoolInputs;
    this.ltoBitcodeFiles = linkContext.ltoBitcodeFiles;
    this.runtimeMiddleman = linkContext.runtimeMiddleman;
    this.runtimeInputs = linkContext.runtimeInputs;
    this.runtimeType = linkContext.runtimeType;
    this.compilationInputs.addTransitive(linkContext.compilationInputs);
    this.linkstamps.addAll(linkContext.linkstamps);
    this.linkopts.addAll(linkContext.linkopts);
    this.linkType = linkContext.linkType;
    this.linkStaticness = linkContext.linkStaticness;
    this.fake = linkContext.fake;
    this.isNativeDeps = linkContext.isNativeDeps;
    this.useTestOnlyFlags = linkContext.useTestOnlyFlags;
  }

  /** Returns the action name for purposes of querying the crosstool. */
  private String getActionName() {
    return linkType.getActionName();
  }
  
  /** Returns linker inputs that are not libraries. */
  public Set<LinkerInput> getObjectFiles() {
    return objectFiles;
  }

  public Set<Artifact> getNonCodeInputs() {
    return nonCodeInputs;
  }

  /**
   * Returns linker inputs that are libraries.
   */
  public NestedSetBuilder<LibraryToLink> getLibraries() {
    return libraries;
  }

  /**
   * Returns inputs arising from the crosstool.
   */
  public NestedSet<Artifact> getCrosstoolInputs() {
    return this.crosstoolInputs;
  }
  
  /**
   * Returns the runtime middleman artifact.
   */
  public Artifact getRuntimeMiddleman() {
    return this.runtimeMiddleman;
  }
  
  /**
   * Returns runtime inputs for this link action.
   */
  public NestedSet<Artifact> getRuntimeInputs() {
    return this.runtimeInputs;
  }

  public ArtifactCategory getRuntimeType() {
    return runtimeType;
  }

  /**
   * Returns compilation inputs for this link action.
   */
  public final NestedSetBuilder<Artifact> getCompilationInputs() {
    return this.compilationInputs;
  }
  
  /**
   * Returns linkstamps for this link action.
   */
  public final Set<Artifact> getLinkstamps() {
    return this.linkstamps;
  }

  /**
   * Returns command line options for this link action.
   */
  public final List<String> getLinkopts() {
    return this.linkopts;
  }
  
  /**
   * Returns the type of this link action.
   */
  public LinkTargetType getLinkType() {
    return this.linkType;
  }
  /**
   * Returns the staticness of this link action.
   */
  public LinkStaticness getLinkStaticness() {
    return this.linkStaticness;
  }
  /**
   * Returns linker inputs that are lto bitcode files in a map from the full bitcode file used by
   * the LTO Backend to the minimized bitcode used by the LTO indexing.
   */
  public ImmutableMap<Artifact, Artifact> getLtoBitcodeFiles() {
    return this.ltoBitcodeFiles;
  }

  /**
   * Returns true for a cc_fake_binary.
   */
  public boolean isFake() {
    return this.fake;
  }
  
  /**
   * Returns true for native dependencies of another language.
   */
  public boolean isNativeDeps() {
    return this.isNativeDeps;
  }
 
  public CppLinkActionBuilder setLinkArtifactFactory(LinkArtifactFactory linkArtifactFactory) {
    this.linkArtifactFactory = linkArtifactFactory;
    return this;
  }
  
  /**
   * Returns true if this link action uses test only flags.
   */
  public boolean useTestOnlyFlags() {
    return this.useTestOnlyFlags;
  }

  /**
   * Maps bitcode object files used by the LTO backends to the corresponding minimized bitcode file
   * used as input to the LTO indexing step.
   */
  private ImmutableSet<LinkerInput> computeLtoIndexingObjectFileInputs() {
    ImmutableSet.Builder<LinkerInput> objectFileInputsBuilder = ImmutableSet.builder();
    for (LinkerInput input : objectFiles) {
      Artifact objectFile = input.getArtifact();
      objectFileInputsBuilder.add(
          LinkerInputs.simpleLinkerInput(
              this.ltoBitcodeFiles.getOrDefault(objectFile, objectFile),
              ArtifactCategory.OBJECT_FILE));
    }
    return objectFileInputsBuilder.build();
  }

  /**
   * Maps bitcode library files used by the LTO backends to the corresponding minimized bitcode file
   * used as input to the LTO indexing step.
   */
  private static NestedSet<LibraryToLink> computeLtoIndexingUniqueLibraries(
      NestedSet<LibraryToLink> originalUniqueLibraries) {
    NestedSetBuilder<LibraryToLink> uniqueLibrariesBuilder = NestedSetBuilder.linkOrder();
    for (LibraryToLink lib : originalUniqueLibraries) {
      if (!lib.containsObjectFiles()) {
        uniqueLibrariesBuilder.add(lib);
        continue;
      }
      ImmutableSet.Builder<Artifact> newObjectFilesBuilder = ImmutableSet.builder();
      for (Artifact a : lib.getObjectFiles()) {
        newObjectFilesBuilder.add(lib.getLtoBitcodeFiles().getOrDefault(a, a));
      }
      uniqueLibrariesBuilder.add(
          LinkerInputs.newInputLibrary(
              lib.getArtifact(),
              lib.getArtifactCategory(),
              lib.getLibraryIdentifier(),
              newObjectFilesBuilder.build(),
              lib.getLtoBitcodeFiles()));
    }
    return uniqueLibrariesBuilder.build();
  }

  /**
   * Returns true if there are any LTO bitcode inputs to this link, either directly transitively via
   * library inputs.
   */
  boolean hasLtoBitcodeInputs() {
    if (!ltoBitcodeFiles.isEmpty()) {
      return true;
    }
    for (LibraryToLink lib : libraries.build()) {
      if (!lib.getLtoBitcodeFiles().isEmpty()) {
        return true;
      }
    }
    return false;
  }

  private Iterable<LtoBackendArtifacts> createLtoArtifacts(
      PathFragment ltoOutputRootPrefix,
      NestedSet<LibraryToLink> uniqueLibraries,
      ImmutableSet<String> features) {
    Set<Artifact> compiled = new LinkedHashSet<>();
    for (LibraryToLink lib : uniqueLibraries) {
      compiled.addAll(lib.getLtoBitcodeFiles().keySet());
    }

    // This flattens the set of object files, so for M binaries and N .o files,
    // this is O(M*N). If we had a nested set of .o files, we could have O(M + N) instead.
    Map<PathFragment, Artifact> allBitcode = new HashMap<>();
    for (LibraryToLink lib : uniqueLibraries) {
      if (!lib.containsObjectFiles()) {
        continue;
      }
      for (Artifact a : lib.getObjectFiles()) {
        if (compiled.contains(a)) {
          allBitcode.put(a.getExecPath(), a);
        }
      }
    }
    for (LinkerInput input : objectFiles) {
      if (this.ltoBitcodeFiles.containsKey(input.getArtifact())) {
        allBitcode.put(input.getArtifact().getExecPath(), input.getArtifact());
      }
    }

    List<String> argv = new ArrayList<>();
    argv.addAll(toolchain.getLinkOptions());
    argv.addAll(cppConfiguration.getCompilerOptions(features));
    ImmutableList.Builder<LtoBackendArtifacts> ltoOutputs = ImmutableList.builder();
    for (Artifact a : allBitcode.values()) {
      LtoBackendArtifacts ltoArtifacts =
          new LtoBackendArtifacts(
              ltoOutputRootPrefix,
              a,
              allBitcode,
              ruleContext,
              configuration,
              linkArtifactFactory,
              featureConfiguration,
              toolchain,
              fdoSupport,
              usePicForLtoBackendActions,
              cppConfiguration.useFission(),
              argv);
      ltoOutputs.add(ltoArtifacts);
    }
    return ltoOutputs.build();
  }

  @VisibleForTesting
  boolean canSplitCommandLine() {
    if (fake) {
      return false;
    }

    if (toolchain == null || !toolchain.supportsParamFiles()) {
      return false;
    }

    switch (linkType) {
        // On Unix, we currently can't split dynamic library links if they have interface outputs.
        // That was probably an unintended side effect of the change that introduced interface
        // outputs.
        // On Windows, We can always split the command line when building DLL.
      case DYNAMIC_LIBRARY:
        return (interfaceOutput == null
            || featureConfiguration.isEnabled(CppRuleClasses.TARGETS_WINDOWS));
      case EXECUTABLE:
      case STATIC_LIBRARY:
      case PIC_STATIC_LIBRARY:
      case ALWAYS_LINK_STATIC_LIBRARY:
      case ALWAYS_LINK_PIC_STATIC_LIBRARY:
        return true;

      default:
        return false;
    }
  }

  /** Builds the Action as configured and returns it. */
  public CppLinkAction build() throws InterruptedException {
    // Executable links do not have library identifiers.
    boolean hasIdentifier = (libraryIdentifier != null);
    boolean isExecutable = linkType.isExecutable();
    Preconditions.checkState(hasIdentifier != isExecutable);
    Preconditions.checkNotNull(featureConfiguration);

    if (interfaceOutput != null && (fake || linkType != LinkTargetType.DYNAMIC_LIBRARY)) {
      throw new RuntimeException(
          "Interface output can only be used " + "with non-fake DYNAMIC_LIBRARY targets");
    }

    if (!featureConfiguration.actionIsConfigured(linkType.getActionName())) {
      ruleContext.ruleError(
          String.format(
              "Expected action_config for '%s' to be configured", linkType.getActionName()));
    }

    final ImmutableList<Artifact> buildInfoHeaderArtifacts =
        !linkstamps.isEmpty()
            ? analysisEnvironment.getBuildInfo(ruleContext, CppBuildInfo.KEY, configuration)
            : ImmutableList.of();

    boolean needWholeArchive =
        wholeArchive
            || needWholeArchive(linkStaticness, linkType, linkopts, isNativeDeps, cppConfiguration);

    NestedSet<LibraryToLink> originalUniqueLibraries = libraries.build();

    // Get the set of object files and libraries containing the correct
    // inputs for this link, depending on whether this is LTO indexing or
    // a native link.
    NestedSet<LibraryToLink> uniqueLibraries;
    ImmutableSet<LinkerInput> objectFileInputs;
    if (isLtoIndexing) {
      objectFileInputs = computeLtoIndexingObjectFileInputs();
      uniqueLibraries = computeLtoIndexingUniqueLibraries(originalUniqueLibraries);
    } else {
      objectFileInputs = ImmutableSet.copyOf(objectFiles);
      uniqueLibraries = originalUniqueLibraries;
    }
    final Iterable<Artifact> objectArtifacts = LinkerInputs.toLibraryArtifacts(objectFileInputs);

    final Iterable<LinkerInput> linkerInputs =
        IterablesChain.<LinkerInput>builder()
            .add(objectFileInputs)
            .add(
                ImmutableIterable.from(
                    Link.mergeInputsCmdLine(
                        uniqueLibraries, needWholeArchive, cppConfiguration.archiveType())))
            .build();

    // ruleContext can only be null during testing. This is kind of ugly.
    final ImmutableSet<String> features =
        (ruleContext == null) ? ImmutableSet.of() : ruleContext.getFeatures();

    final LibraryToLink outputLibrary = linkType.isExecutable()
        ? null
        : LinkerInputs.newInputLibrary(output,
            linkType.getLinkerOutput(),
            libraryIdentifier,
            objectArtifacts, this.ltoBitcodeFiles);
    final LibraryToLink interfaceOutputLibrary =
        (interfaceOutput == null)
            ? null
            : LinkerInputs.newInputLibrary(interfaceOutput,
                ArtifactCategory.DYNAMIC_LIBRARY,
                libraryIdentifier,
                objectArtifacts, this.ltoBitcodeFiles);

    final ImmutableMap<Artifact, Artifact> linkstampMap =
        mapLinkstampsToOutputs(linkstamps, ruleContext, configuration, output, linkArtifactFactory);

    PathFragment ltoOutputRootPrefix = null;
    if (isLtoIndexing && allLtoArtifacts == null) {
      ltoOutputRootPrefix =
          FileSystemUtils.appendExtension(
              output.getRootRelativePath(), ".lto");
      // Use the originalUniqueLibraries which contains the full bitcode files
      // needed by the LTO backends (as opposed to the minimized bitcode files
      // that can be used by the LTO indexing step).
      allLtoArtifacts = createLtoArtifacts(ltoOutputRootPrefix, originalUniqueLibraries, features);
    }

    @Nullable Artifact thinltoParamFile = null;
    if (allLtoArtifacts != null) {
      // Create artifact for the file that the LTO indexing step will emit
      // object file names into for any that were included in the link as
      // determined by the linker's symbol resolution. It will be used to
      // provide the inputs for the subsequent final native object link.
      // Note that the paths emitted into this file will have their prefixes
      // replaced with the final output directory, so they will be the paths
      // of the native object files not the input bitcode files.
      PathFragment linkerParamFileRootPath =
          ParameterFile.derivePath(output.getRootRelativePath(), "lto-final");
      thinltoParamFile =
          linkArtifactFactory.create(ruleContext, configuration, linkerParamFileRootPath);
    }

    final ImmutableList<Artifact> actionOutputs;
    if (isLtoIndexing) {
      ImmutableList.Builder<Artifact> builder = ImmutableList.builder();
      for (LtoBackendArtifacts ltoA : allLtoArtifacts) {
        ltoA.addIndexingOutputs(builder);
      }
      if (thinltoParamFile != null) {
        builder.add(thinltoParamFile);
      }
      actionOutputs = builder.build();
    } else {
      actionOutputs =
          constructOutputs(
              output,
              Iterables.concat(linkstampMap.values(), linkActionOutputs.build()),
              interfaceOutputLibrary == null ? null : interfaceOutputLibrary.getArtifact(),
              symbolCounts);
    }

    ImmutableList<LinkerInput> runtimeLinkerInputs =
        ImmutableList.copyOf(LinkerInputs.simpleLinkerInputs(runtimeInputs, runtimeType));

    PathFragment paramRootPath =
        ParameterFile.derivePath(output.getRootRelativePath(), (isLtoIndexing) ? "lto-index" : "2");

    @Nullable
    final Artifact paramFile =
        canSplitCommandLine()
            ? linkArtifactFactory.create(ruleContext, configuration, paramRootPath)
            : null;

    // Add build variables necessary to template link args into the crosstool.
    Variables.Builder buildVariablesBuilder = new Variables.Builder(toolchain.getBuildVariables());
    CppLinkVariablesExtension variablesExtension =
        isLtoIndexing
            ? new CppLinkVariablesExtension(
                configuration,
                /* linkstampMap= */ ImmutableMap.of(),
                needWholeArchive,
                linkerInputs,
                runtimeLinkerInputs,
                /* output= */ null,
                paramFile,
                thinltoParamFile,
                ltoOutputRootPrefix,
                /* interfaceLibraryBuilder= */ null,
                /* interfaceLibraryOutput= */ null)
            : new CppLinkVariablesExtension(
                configuration,
                linkstampMap,
                needWholeArchive,
                linkerInputs,
                runtimeLinkerInputs,
                output,
                paramFile,
                thinltoParamFile,
                /* ltoOutputRootPrefix= */ PathFragment.EMPTY_FRAGMENT,
                toolchain.getInterfaceSoBuilder(),
                interfaceOutput);
    variablesExtension.addVariables(buildVariablesBuilder);
    for (VariablesExtension extraVariablesExtension : variablesExtensions) {
      extraVariablesExtension.addVariables(buildVariablesBuilder);
    }
    Variables buildVariables = buildVariablesBuilder.build();

    Preconditions.checkArgument(
        linkType != LinkTargetType.INTERFACE_DYNAMIC_LIBRARY,
        "you can't link an interface dynamic library directly");
    if (linkType != LinkTargetType.DYNAMIC_LIBRARY) {
      Preconditions.checkArgument(
          interfaceOutput == null,
          "interface output may only be non-null for dynamic library links");
    }
    if (linkType.staticness() == Staticness.STATIC) {
      // solib dir must be null for static links
      runtimeSolibDir = null;

      Preconditions.checkArgument(
          linkStaticness == LinkStaticness.FULLY_STATIC, "static library link must be static");
      Preconditions.checkArgument(
          symbolCounts == null, "the symbol counts output must be null for static links");
      Preconditions.checkArgument(
          !isNativeDeps, "the native deps flag must be false for static links");
      Preconditions.checkArgument(
          !needWholeArchive, "the need whole archive flag must be false for static links");
    }

    LinkCommandLine.Builder linkCommandLineBuilder =
        new LinkCommandLine.Builder(configuration, getOwner(), ruleContext)
            .setLinkerInputs(linkerInputs)
            .setRuntimeInputs(runtimeLinkerInputs)
            .setLinkTargetType(linkType)
            .setLinkStaticness(linkStaticness)
            .setFeatures(features)
            .setRuntimeSolibDir(linkType.staticness() == Staticness.STATIC ? null : runtimeSolibDir)
            .setNativeDeps(isNativeDeps)
            .setUseTestOnlyFlags(useTestOnlyFlags)
            .setParamFile(paramFile)
            .setToolchain(toolchain)
            .setFdoSupport(fdoSupport.getFdoSupport())
            .setBuildVariables(buildVariables)
            .setFeatureConfiguration(featureConfiguration);

    // TODO(b/62693279): Cleanup once internal crosstools specify ifso building correctly.
    if (shouldUseLinkDynamicLibraryTool()) {
      linkCommandLineBuilder.forceToolPath(
          toolchain.getLinkDynamicLibraryTool().getExecPathString());
    }

    if (!isLtoIndexing) {
      linkCommandLineBuilder
          .setOutput(output)
          .setBuildInfoHeaderArtifacts(buildInfoHeaderArtifacts)
          .setLinkstamps(linkstampMap)
          .setLinkopts(ImmutableList.copyOf(linkopts))
          .setAdditionalLinkstampDefines(additionalLinkstampDefines);
    } else {
      List<String> opts = new ArrayList<>(linkopts);
      opts.addAll(featureConfiguration.getCommandLine("lto-indexing", buildVariables));
      opts.addAll(cppConfiguration.getLtoIndexOptions());
      linkCommandLineBuilder.setLinkopts(ImmutableList.copyOf(opts));
    }

    LinkCommandLine linkCommandLine = linkCommandLineBuilder.build();

    // Compute the set of inputs - we only need stable order here.
    NestedSetBuilder<Artifact> dependencyInputsBuilder = NestedSetBuilder.stableOrder();
    dependencyInputsBuilder.addTransitive(crosstoolInputs);
    dependencyInputsBuilder.addTransitive(linkActionInputs.build());
    // TODO(b/62693279): Cleanup once internal crosstools specify ifso building correctly.
    if (shouldUseLinkDynamicLibraryTool()) {
      dependencyInputsBuilder.add(toolchain.getLinkDynamicLibraryTool());
    }
    if (runtimeMiddleman != null) {
      dependencyInputsBuilder.add(runtimeMiddleman);
    }
    if (!isLtoIndexing) {
      dependencyInputsBuilder.addAll(buildInfoHeaderArtifacts);
      dependencyInputsBuilder.addAll(linkstamps);
      dependencyInputsBuilder.addTransitive(compilationInputs.build());
    }
    if (defFile != null) {
      dependencyInputsBuilder.add(defFile);
    }

    Iterable<Artifact> expandedInputs =
        LinkerInputs.toLibraryArtifacts(
            Link.mergeInputsDependencies(
                uniqueLibraries, needWholeArchive, cppConfiguration.archiveType()));
    Iterable<Artifact> expandedNonLibraryInputs = LinkerInputs.toLibraryArtifacts(objectFileInputs);

    if (!isLtoIndexing && allLtoArtifacts != null) {
      // We are doing LTO, and this is the real link, so substitute
      // the LTO bitcode files with the real object files they were translated into.
      Map<Artifact, Artifact> ltoMapping = new HashMap<>();
      for (LtoBackendArtifacts a : allLtoArtifacts) {
        ltoMapping.put(a.getBitcodeFile(), a.getObjectFile());
      }

      // Handle libraries.
      List<Artifact> renamedInputs = new ArrayList<>();
      for (Artifact a : expandedInputs) {
        Artifact renamed = ltoMapping.get(a);
        renamedInputs.add(renamed == null ? a : renamed);
      }
      expandedInputs = renamedInputs;

      // Handle non-libraries.
      List<Artifact> renamedNonLibraryInputs = new ArrayList<>();
      for (Artifact a : expandedNonLibraryInputs) {
        Artifact renamed = ltoMapping.get(a);
        renamedNonLibraryInputs.add(renamed == null ? a : renamed);
      }
      expandedNonLibraryInputs = renamedNonLibraryInputs;
    }

    // getPrimaryInput returns the first element, and that is a public interface - therefore the
    // order here is important.
    IterablesChain.Builder<Artifact> inputsBuilder =
        IterablesChain.<Artifact>builder()
            .add(ImmutableList.copyOf(expandedNonLibraryInputs))
            .add(ImmutableList.copyOf(nonCodeInputs))
            .add(dependencyInputsBuilder.build())
            .add(ImmutableIterable.from(expandedInputs));

    if (thinltoParamFile != null && !isLtoIndexing) {
      inputsBuilder.add(ImmutableList.of(thinltoParamFile));
    }
    if (linkCommandLine.getParamFile() != null) {
      inputsBuilder.add(ImmutableList.of(linkCommandLine.getParamFile()));
      Action parameterFileWriteAction =
          new ParameterFileWriteAction(
              getOwner(),
              paramFile,
              linkCommandLine.paramCmdLine(),
              ParameterFile.ParameterFileType.UNQUOTED,
              ISO_8859_1);
      analysisEnvironment.registerAction(parameterFileWriteAction);
    }

    ImmutableMap<String, String> toolchainEnv =
        featureConfiguration.getEnvironmentVariables(getActionName(), buildVariables);

    // If the crosstool uses action_configs to configure cc compilation, collect execution info
    // from there, otherwise, use no execution info.
    // TODO(b/27903698): Assert that the crosstool has an action_config for this action.
    ImmutableSet.Builder<String> executionRequirements = ImmutableSet.builder();
    if (featureConfiguration.actionIsConfigured(getActionName())) {
      executionRequirements.addAll(
          featureConfiguration.getToolForAction(getActionName()).getExecutionRequirements());
    }

    return new CppLinkAction(
        getOwner(),
        mnemonic,
        inputsBuilder.deduplicate().build(),
        actionOutputs,
        cppConfiguration,
        outputLibrary,
        output,
        interfaceOutputLibrary,
        fake,
        isLtoIndexing,
        linkCommandLine,
        configuration.getVariableShellEnvironment(),
        configuration.getLocalShellEnvironment(),
        toolchainEnv,
        executionRequirements.build(),
        toolchain);
  }

  private boolean shouldUseLinkDynamicLibraryTool() {
    return linkType.equals(LinkTargetType.DYNAMIC_LIBRARY)
        && cppConfiguration.supportsInterfaceSharedObjects()
        && !featureConfiguration.hasConfiguredLinkerPathInActionConfig();
  }

  /** The default heuristic on whether we need to use whole-archive for the link. */
  private static boolean needWholeArchive(
      LinkStaticness staticness,
      LinkTargetType type,
      Collection<String> linkopts,
      boolean isNativeDeps,
      CppConfiguration cppConfig) {
    boolean fullyStatic = (staticness == LinkStaticness.FULLY_STATIC);
    boolean mostlyStatic = (staticness == LinkStaticness.MOSTLY_STATIC);
    boolean sharedLinkopts =
        type == LinkTargetType.DYNAMIC_LIBRARY
            || linkopts.contains("-shared")
            || cppConfig.hasSharedLinkOption();
    return (isNativeDeps || cppConfig.legacyWholeArchive())
        && (fullyStatic || mostlyStatic)
        && sharedLinkopts;
  }

  private static ImmutableList<Artifact> constructOutputs(
      Artifact primaryOutput, Iterable<Artifact> outputList, Artifact... outputs) {
    return new ImmutableList.Builder<Artifact>()
        .add(primaryOutput)
        .addAll(outputList)
        .addAll(CollectionUtils.asListWithoutNulls(outputs))
        .build();
  }

  /**
   * Translates a collection of linkstamp source files to an immutable mapping from source files to
   * object files. In other words, given a set of source files, this method determines the output
   * path to which each file should be compiled.
   *
   * @param linkstamps collection of linkstamp source files
   * @param ruleContext the rule for which this link is being performed
   * @param outputBinary the binary output path for this link
   * @return an immutable map that pairs each source file with the corresponding object file that
   *     should be fed into the link
   */
  public static ImmutableMap<Artifact, Artifact> mapLinkstampsToOutputs(
      Collection<Artifact> linkstamps,
      RuleContext ruleContext,
      BuildConfiguration configuration,
      Artifact outputBinary,
      LinkArtifactFactory linkArtifactFactory) {
    ImmutableMap.Builder<Artifact, Artifact> mapBuilder = ImmutableMap.builder();

    PathFragment outputBinaryPath = outputBinary.getRootRelativePath();
    PathFragment stampOutputDirectory =
        outputBinaryPath
            .getParentDirectory()
            .getRelative(CppHelper.OBJS)
            .getRelative(outputBinaryPath.getBaseName());

    for (Artifact linkstamp : linkstamps) {
      PathFragment stampOutputPath =
          stampOutputDirectory.getRelative(
              FileSystemUtils.replaceExtension(linkstamp.getRootRelativePath(), ".o"));
      mapBuilder.put(
          linkstamp,
          // Note that link stamp actions can be shared between link actions that output shared
          // native dep libraries.
          linkArtifactFactory.create(ruleContext, configuration, stampOutputPath));
    }
    return mapBuilder.build();
  }

  protected ActionOwner getOwner() {
    return ruleContext.getActionOwner();
  }
  
  /** Sets the mnemonic for the link action. */
  public CppLinkActionBuilder setMnemonic(String mnemonic) {
    this.mnemonic = mnemonic;
    return this;
  }

  /** Set the crosstool inputs required for the action. */
  public CppLinkActionBuilder setCrosstoolInputs(NestedSet<Artifact> inputs) {
    this.crosstoolInputs = inputs;
    return this;
  }

  /** Returns the set of LTO artifacts created during build() */
  public Iterable<LtoBackendArtifacts> getAllLtoBackendArtifacts() {
    return allLtoArtifacts;
  }

  /**
   * This is the LTO indexing step, rather than the real link.
   *
   * <p>When using this, build() will store allLtoArtifacts as a side-effect so the next build()
   * call can emit the real link. Do not call addInput() between the two build() calls.
   */
  public CppLinkActionBuilder setLtoIndexing(boolean ltoIndexing) {
    this.isLtoIndexing = ltoIndexing;
    return this;
  }

  /** Sets flag for using PIC in any scheduled LTO Backend actions. */
  public CppLinkActionBuilder setUsePicForLtoBackendActions(boolean usePic) {
    this.usePicForLtoBackendActions = usePic;
    return this;
  }

  /** Sets the C++ runtime library inputs for the action. */
  public CppLinkActionBuilder setRuntimeInputs(
      ArtifactCategory runtimeType, Artifact middleman, NestedSet<Artifact> inputs) {
    Preconditions.checkArgument((middleman == null) == inputs.isEmpty());
    this.runtimeType = runtimeType;
    this.runtimeMiddleman = middleman;
    this.runtimeInputs = inputs;
    return this;
  }

  /** Adds a variables extension to template the toolchain for this link action. */
  public CppLinkActionBuilder addVariablesExtension(VariablesExtension variablesExtension) {
    this.variablesExtensions.add(variablesExtension);
    return this;
  }

  /** Adds variables extensions to template the toolchain for this link action. */
  public CppLinkActionBuilder addVariablesExtensions(List<VariablesExtension> variablesExtensions) {
    for (VariablesExtension variablesExtension : variablesExtensions) {
      addVariablesExtension(variablesExtension);
    }
     return this;
   }
  
  /**
   * Sets the interface output of the link. A non-null argument can only be provided if the link
   * type is {@code DYNAMIC_LIBRARY} and fake is false.
   */
  public CppLinkActionBuilder setInterfaceOutput(Artifact interfaceOutput) {
    this.interfaceOutput = interfaceOutput;
    return this;
  }

  public CppLinkActionBuilder setSymbolCountsOutput(Artifact symbolCounts) {
    this.symbolCounts = symbolCounts;
    return this;
  }

  /**
   * Add additional inputs needed for the linkstamp compilation that is being done as part of the
   * link.
   */
  public CppLinkActionBuilder addCompilationInputs(Iterable<Artifact> inputs) {
    this.compilationInputs.addAll(inputs);
    return this;
  }

  public CppLinkActionBuilder addTransitiveCompilationInputs(NestedSet<Artifact> inputs) {
    this.compilationInputs.addTransitive(inputs);
    return this;
  }

  private void addObjectFile(LinkerInput input) {
    // We skip file extension checks for TreeArtifacts because they represent directory artifacts
    // without a file extension.
    String name = input.getArtifact().getFilename();
    Preconditions.checkArgument(
        input.getArtifact().isTreeArtifact() || Link.OBJECT_FILETYPES.matches(name), name);
    this.objectFiles.add(input);
  }

  public CppLinkActionBuilder addLtoBitcodeFiles(ImmutableMap<Artifact, Artifact> files) {
    Preconditions.checkState(ltoBitcodeFiles == null);
    ltoBitcodeFiles = files;
    return this;
  }

  public CppLinkActionBuilder setDefFile(Artifact defFile) {
    this.defFile = defFile;
    return this;
  }

  /**
   * Adds a single object file to the set of inputs.
   */
  public CppLinkActionBuilder addObjectFile(Artifact input) {
    addObjectFile(LinkerInputs.simpleLinkerInput(input, ArtifactCategory.OBJECT_FILE));
    return this;
  }

  /**
   * Adds object files to the linker action.
   */
  public CppLinkActionBuilder addObjectFiles(Iterable<Artifact> inputs) {
    for (Artifact input : inputs) {
      addObjectFile(LinkerInputs.simpleLinkerInput(input, ArtifactCategory.OBJECT_FILE));
    }
    return this;
  }

  /**
   * Adds non-code files to the set of inputs. They will not be passed to the linker command line
   * unless that is explicitly modified, too.
   */
  public CppLinkActionBuilder addNonCodeInputs(Iterable<Artifact> inputs) {
    for (Artifact input : inputs) {
      addNonCodeInput(input);
    }

    return this;
  }

  /**
   * Adds a single non-code file to the set of inputs. It will not be passed to the linker command
   * line unless that is explicitly modified, too.
   */
  public CppLinkActionBuilder addNonCodeInput(Artifact input) {
    String basename = input.getFilename();
    Preconditions.checkArgument(!Link.ARCHIVE_LIBRARY_FILETYPES.matches(basename), basename);
    Preconditions.checkArgument(!Link.SHARED_LIBRARY_FILETYPES.matches(basename), basename);
    Preconditions.checkArgument(!Link.OBJECT_FILETYPES.matches(basename), basename);

    this.nonCodeInputs.add(input);
    return this;
  }

  public CppLinkActionBuilder addFakeObjectFiles(Iterable<Artifact> inputs) {
    for (Artifact input : inputs) {
      addObjectFile(LinkerInputs.fakeLinkerInput(input));
    }
    return this;
  }

  private void checkLibrary(LibraryToLink input) {
    String name = input.getArtifact().getFilename();
    Preconditions.checkArgument(
        Link.ARCHIVE_LIBRARY_FILETYPES.matches(name) || Link.SHARED_LIBRARY_FILETYPES.matches(name),
        "'%s' is not a library file",
        input);
  }

  /**
   * Adds a single artifact to the set of inputs. The artifact must be an archive or a shared
   * library. Note that all directly added libraries are implicitly ordered before all nested sets
   * added with {@link #addLibraries}, even if added in the opposite order.
   */
  public CppLinkActionBuilder addLibrary(LibraryToLink input) {
    checkLibrary(input);
    libraries.add(input);
    return this;
  }

  /**
   * Adds multiple artifact to the set of inputs. The artifacts must be archives or shared
   * libraries.
   */
  public CppLinkActionBuilder addLibraries(NestedSet<LibraryToLink> inputs) {
    for (LibraryToLink input : inputs) {
      checkLibrary(input);
    }
    this.libraries.addTransitive(inputs);
    return this;
  }

  /**
   * Sets the type of ELF file to be created (.a, .so, .lo, executable). The default is {@link
   * LinkTargetType#STATIC_LIBRARY}.
   */
  public CppLinkActionBuilder setLinkType(LinkTargetType linkType) {
    this.linkType = linkType;
    return this;
  }

  /**
   * Sets the degree of "staticness" of the link: fully static (static binding of all symbols),
   * mostly static (use dynamic binding only for symbols from glibc), dynamic (use dynamic binding
   * wherever possible). The default is {@link LinkStaticness#FULLY_STATIC}.
   */
  public CppLinkActionBuilder setLinkStaticness(LinkStaticness linkStaticness) {
    this.linkStaticness = linkStaticness;
    return this;
  }

  /**
   * Sets the identifier of the library produced by the action. See
   * {@link LinkerInputs.LibraryToLink#getLibraryIdentifier()}
   */
  public CppLinkActionBuilder setLibraryIdentifier(String libraryIdentifier) {
    this.libraryIdentifier = libraryIdentifier;
    return this;
  }

  /**
   * Adds a C++ source file which will be compiled at link time. This is used to embed various
   * values from the build system into binaries to identify their provenance.
   *
   * <p>Link stamps are also automatically added to the inputs.
   */
  public CppLinkActionBuilder addLinkstamps(Map<Artifact, NestedSet<Artifact>> linkstamps) {
    this.linkstamps.addAll(linkstamps.keySet());
    // Add inputs for linkstamping.
    if (!linkstamps.isEmpty()) {
      for (Map.Entry<Artifact, NestedSet<Artifact>> entry : linkstamps.entrySet()) {
        addCompilationInputs(entry.getValue());
      }
    }
    return this;
  }

  public CppLinkActionBuilder setAdditionalLinkstampDefines(
      ImmutableList<String> additionalLinkstampDefines) {
    this.additionalLinkstampDefines = Preconditions.checkNotNull(additionalLinkstampDefines);
    return this;
  }

  /** Adds an additional linker option. */
  public CppLinkActionBuilder addLinkopt(String linkopt) {
    this.linkopts.add(linkopt);
    return this;
  }

  /**
   * Adds multiple linker options at once.
   *
   * @see #addLinkopt(String)
   */
  public CppLinkActionBuilder addLinkopts(Collection<String> linkopts) {
    this.linkopts.addAll(linkopts);
    return this;
  }

  /**
   * Merges the given link params into this builder by calling {@link #addLinkopts}, {@link
   * #addLibraries}, and {@link #addLinkstamps}.
   */
  public CppLinkActionBuilder addLinkParams(
      CcLinkParams linkParams, RuleErrorConsumer errorListener) throws InterruptedException {
    addLinkopts(linkParams.flattenedLinkopts());
    addLibraries(linkParams.getLibraries());
    ExtraLinkTimeLibraries extraLinkTimeLibraries = linkParams.getExtraLinkTimeLibraries();
    if (extraLinkTimeLibraries != null) {
      for (ExtraLinkTimeLibrary extraLibrary : extraLinkTimeLibraries.getExtraLibraries()) {
        addLibraries(extraLibrary.buildLibraries(ruleContext));
      }
    }
    addLinkstamps(CppHelper.resolveLinkstamps(errorListener, linkParams));
    return this;
  }

  /** Sets whether this link action will be used for a cc_fake_binary; false by default. */
  public CppLinkActionBuilder setFake(boolean fake) {
    this.fake = fake;
    return this;
  }

  /** Sets whether this link action is used for a native dependency library. */
  public CppLinkActionBuilder setNativeDeps(boolean isNativeDeps) {
    this.isNativeDeps = isNativeDeps;
    return this;
  }

  /**
   * Setting this to true overrides the default whole-archive computation and force-enables whole
   * archives for every archive in the link. This is only necessary for linking executable binaries
   * that are supposed to export symbols.
   *
   * <p>Usually, the link action while use whole archives for dynamic libraries that are native deps
   * (or the legacy whole archive flag is enabled), and that are not dynamically linked.
   *
   * <p>(Note that it is possible to build dynamic libraries with cc_binary rules by specifying
   * linkshared = 1, and giving the rule a name that matches the pattern {@code
   * lib&lt;name&gt;.so}.)
   */
  public CppLinkActionBuilder setWholeArchive(boolean wholeArchive) {
    this.wholeArchive = wholeArchive;
    return this;
  }

  /**
   * Sets whether this link action should use test-specific flags (e.g. $EXEC_ORIGIN instead of
   * $ORIGIN for the solib search path or lazy binding); false by default.
   */
  public CppLinkActionBuilder setUseTestOnlyFlags(boolean useTestOnlyFlags) {
    this.useTestOnlyFlags = useTestOnlyFlags;
    return this;
  }

  /**
   * Sets the name of the directory where the solib symlinks for the dynamic runtime libraries live.
   * This is usually automatically set from the cc_toolchain.
   */
  public CppLinkActionBuilder setRuntimeSolibDir(PathFragment runtimeSolibDir) {
    this.runtimeSolibDir = runtimeSolibDir;
    return this;
  }
  
  /**
   * Adds an extra input artifact to the link action.
   */
  public CppLinkActionBuilder addActionInput(Artifact input) {
    this.linkActionInputs.add(input);
    return this;
  }
  
  /**
   * Adds extra input artifacts to the link action.
   */
  public CppLinkActionBuilder addActionInputs(Iterable<Artifact> inputs) {
    this.linkActionInputs.addAll(inputs);
    return this;
  }
  
  /**
   * Adds extra input artifacts to the link actions.
   */
  public CppLinkActionBuilder addTransitiveActionInputs(NestedSet<Artifact> inputs) {
    this.linkActionInputs.addTransitive(inputs);
    return this;
  }

  /** Adds an extra output artifact to the link action. */
  public CppLinkActionBuilder addActionOutput(Artifact output) {
    this.linkActionOutputs.add(output);
    return this;
  }

  private static class LinkArgCollector {
    ImmutableSet<String> runtimeLibrarySearchDirectories;
    ImmutableSet<String> librarySearchDirectories;
    SequenceBuilder librariesToLink;

    public void setRuntimeLibrarySearchDirectories(
        ImmutableSet<String> runtimeLibrarySearchDirectories) {
      this.runtimeLibrarySearchDirectories = runtimeLibrarySearchDirectories;
    }

    public void setLibrariesToLink(SequenceBuilder librariesToLink) {
      this.librariesToLink = librariesToLink;
    }

    public void setLibrarySearchDirectories(ImmutableSet<String> librarySearchDirectories) {
      this.librarySearchDirectories = librarySearchDirectories;
    }

    public ImmutableSet<String> getRuntimeLibrarySearchDirectories() {
      return runtimeLibrarySearchDirectories;
    }

    public SequenceBuilder getLibrariesToLink() {
      return librariesToLink;
    }

    public ImmutableSet<String> getLibrarySearchDirectories() {
      return librarySearchDirectories;
    }

  }

  private class CppLinkVariablesExtension implements VariablesExtension {

    private final BuildConfiguration configuration;
    private final ImmutableMap<Artifact, Artifact> linkstampMap;
    private final boolean needWholeArchive;
    private final Iterable<LinkerInput> linkerInputs;
    private final ImmutableList<LinkerInput> runtimeLinkerInputs;
    private final Artifact outputArtifact;
    private final Artifact interfaceLibraryBuilder;
    private final Artifact interfaceLibraryOutput;
    private final Artifact paramFile;
    private final Artifact thinltoParamFile;
    private final PathFragment ltoOutputRootPrefix;

    private final LinkArgCollector linkArgCollector = new LinkArgCollector();

    public CppLinkVariablesExtension(
        BuildConfiguration configuration,
        ImmutableMap<Artifact, Artifact> linkstampMap,
        boolean needWholeArchive,
        Iterable<LinkerInput> linkerInputs,
        ImmutableList<LinkerInput> runtimeLinkerInputs,
        Artifact output,
        Artifact paramFile,
        Artifact thinltoParamFile,
        PathFragment ltoOutputRootPrefix,
        Artifact interfaceLibraryBuilder,
        Artifact interfaceLibraryOutput) {
      this.configuration = configuration;
      this.linkstampMap = linkstampMap;
      this.needWholeArchive = needWholeArchive;
      this.linkerInputs = linkerInputs;
      this.runtimeLinkerInputs = runtimeLinkerInputs;
      this.outputArtifact = output;
      this.interfaceLibraryBuilder = interfaceLibraryBuilder;
      this.interfaceLibraryOutput = interfaceLibraryOutput;
      this.paramFile = paramFile;
      this.thinltoParamFile = thinltoParamFile;
      this.ltoOutputRootPrefix = ltoOutputRootPrefix;

      addInputFileLinkOptions(linkArgCollector);
    }

    @Override
    public void addVariables(Variables.Builder buildVariables) {

      // symbol counting
      if (symbolCounts != null) {
        buildVariables.addStringVariable(
            SYMBOL_COUNTS_OUTPUT_VARIABLE, symbolCounts.getExecPathString());
      }

      // linkstamp
      ImmutableSet.Builder<String> linkstampPaths = ImmutableSet.builder();
      for (Artifact linkstampOutput : linkstampMap.values()) {
        linkstampPaths.add(linkstampOutput.getExecPathString());
      }

      buildVariables.addStringSequenceVariable(
          LINKSTAMP_PATHS_VARIABLE, linkstampPaths.build());

      // pic
      if (cppConfiguration.forcePic()) {
        buildVariables.addStringVariable(FORCE_PIC_VARIABLE, "");
      }

      if (cppConfiguration.shouldStripBinaries()) {
        buildVariables.addStringVariable(STRIP_DEBUG_SYMBOLS_VARIABLE, "");
      }

      if (getLinkType().staticness().equals(Staticness.DYNAMIC) && cppConfiguration.useFission()) {
        buildVariables.addStringVariable(IS_USING_FISSION_VARIABLE, "");
      }

      if (useTestOnlyFlags()) {
        buildVariables.addIntegerVariable(IS_CC_TEST_VARIABLE, 1);
        buildVariables.addStringVariable(IS_CC_TEST_LINK_ACTION_VARIABLE, "");
      } else {
        buildVariables.addIntegerVariable(IS_CC_TEST_VARIABLE, 0);
        buildVariables.addStringVariable(IS_NOT_CC_TEST_LINK_ACTION_VARIABLE, "");
      }

      // TODO(b/37271982): Remove after blaze with ar action_config release
      buildVariables.addStringVariable(USES_ACTION_CONFIG_FOR_AR_VARIABLE, "");

      if (linkArgCollector.getRuntimeLibrarySearchDirectories() != null) {
        buildVariables.addStringSequenceVariable(
            RUNTIME_LIBRARY_SEARCH_DIRECTORIES_VARIABLE,
            linkArgCollector.getRuntimeLibrarySearchDirectories());
      }

      buildVariables.addCustomBuiltVariable(
          LIBRARIES_TO_LINK_VARIABLE, linkArgCollector.getLibrariesToLink());

      buildVariables.addStringSequenceVariable(
          LIBRARY_SEARCH_DIRECTORIES_VARIABLE, linkArgCollector.getLibrarySearchDirectories());

      if (paramFile != null) {
        buildVariables.addStringVariable(LINKER_PARAM_FILE_VARIABLE, paramFile.getExecPathString());
      }

      // output exec path
      if (outputArtifact != null) {
        buildVariables.addStringVariable(
            OUTPUT_EXECPATH_VARIABLE, outputArtifact.getExecPathString());
      }

      if (isLtoIndexing()) {
        if (thinltoParamFile != null) {
          // This is a lto-indexing action and we want it to populate param file.
          buildVariables.addStringVariable(
              THINLTO_INDEXING_PARAM_FILE_VARIABLE, thinltoParamFile.getExecPathString());
          // TODO(b/33846234): Remove once all the relevant crosstools don't depend on the variable.
          buildVariables.addStringVariable(
              "thinlto_optional_params_file", "=" + thinltoParamFile.getExecPathString());
        } else {
          buildVariables.addStringVariable(THINLTO_INDEXING_PARAM_FILE_VARIABLE, "");
          // TODO(b/33846234): Remove once all the relevant crosstools don't depend on the variable.
          buildVariables.addStringVariable("thinlto_optional_params_file", "");
        }
        buildVariables.addStringVariable(
            THINLTO_PREFIX_REPLACE_VARIABLE,
            configuration.getBinDirectory().getExecPathString()
                + ";"
                + configuration.getBinDirectory().getExecPath().getRelative(ltoOutputRootPrefix));
        buildVariables.addStringVariable(
            THINLTO_OBJECT_SUFFIX_REPLACE_VARIABLE,
            Iterables.getOnlyElement(CppFileTypes.LTO_INDEXING_OBJECT_FILE.getExtensions())
                + ";"
                + Iterables.getOnlyElement(CppFileTypes.OBJECT_FILE.getExtensions()));
      } else {
        if (thinltoParamFile != null) {
          // This is a normal link action and we need to use param file created by lto-indexing.
          buildVariables.addStringVariable(
              THINLTO_PARAM_FILE_VARIABLE, thinltoParamFile.getExecPathString());
        }
      }
      boolean shouldGenerateInterfaceLibrary =
          outputArtifact != null
              && interfaceLibraryBuilder != null
              && interfaceLibraryOutput != null;
      buildVariables.addStringVariable(
          GENERATE_INTERFACE_LIBRARY_VARIABLE, shouldGenerateInterfaceLibrary ? "yes" : "no");
      buildVariables.addStringVariable(
          INTERFACE_LIBRARY_BUILDER_VARIABLE,
          shouldGenerateInterfaceLibrary ? interfaceLibraryBuilder.getExecPathString() : "ignored");
      buildVariables.addStringVariable(
          INTERFACE_LIBRARY_INPUT_VARIABLE,
          shouldGenerateInterfaceLibrary ? outputArtifact.getExecPathString() : "ignored");
      buildVariables.addStringVariable(
          INTERFACE_LIBRARY_OUTPUT_VARIABLE,
          shouldGenerateInterfaceLibrary ? interfaceLibraryOutput.getExecPathString() : "ignored");

      if (defFile != null) {
        buildVariables.addStringVariable(DEF_FILE_PATH_VARIABLE, defFile.getExecPathString());
      }

      fdoSupport.getFdoSupport().getLinkOptions(featureConfiguration, buildVariables);
    }

    private boolean isLtoIndexing() {
      return !ltoOutputRootPrefix.equals(PathFragment.EMPTY_FRAGMENT);
    }

    private boolean isSharedNativeLibrary() {
      return isNativeDeps && cppConfiguration.shareNativeDeps();
    }

    /**
     * When linking a shared library fully or mostly static then we need to link in *all* dependent
     * files, not just what the shared library needs for its own code. This is done by wrapping all
     * objects/libraries with -Wl,-whole-archive and -Wl,-no-whole-archive. For this case the
     * globalNeedWholeArchive parameter must be set to true. Otherwise only library objects (.lo)
     * need to be wrapped with -Wl,-whole-archive and -Wl,-no-whole-archive.
     *
     * <p>TODO: Factor out of the bazel binary into build variables for crosstool action_configs.
     */
    private void addInputFileLinkOptions(LinkArgCollector linkArgCollector) {
      ImmutableSet.Builder<String> librarySearchDirectories = ImmutableSet.builder();
      ImmutableSet.Builder<String> runtimeRpathRoots = ImmutableSet.builder();
      ImmutableSet.Builder<String> rpathRootsForExplicitSoDeps = ImmutableSet.builder();

      // List of command line parameters that need to be placed *outside* of
      // --whole-archive ... --no-whole-archive.
      SequenceBuilder librariesToLink = new SequenceBuilder();

      PathFragment solibDir =
          configuration
              .getBinDirectory(ruleContext.getRule().getRepository())
              .getExecPath()
              .getRelative(toolchain.getSolibDirectory());
      String runtimeSolibName = runtimeSolibDir != null ? runtimeSolibDir.getBaseName() : null;
      boolean runtimeRpath =
          runtimeSolibDir != null
              && (linkType == LinkTargetType.DYNAMIC_LIBRARY
                  || (linkType == LinkTargetType.EXECUTABLE
                      && linkStaticness == LinkStaticness.DYNAMIC));

      if (runtimeRpath) {
        if (isNativeDeps) {
          runtimeRpathRoots.add(".");
        }
        runtimeRpathRoots.add(runtimeSolibName + "/");
      }

      String rpathRoot;
      // Calculate the correct relative value for the "-rpath" link option (which sets
      // the search path for finding shared libraries).
      if (isSharedNativeLibrary()) {
        // For shared native libraries, special symlinking is applied to ensure C++
        // runtimes are available under $ORIGIN/_solib_[arch]. So we set the RPATH to find
        // them.
        //
        // Note that we have to do this because $ORIGIN points to different paths for
        // different targets. In other words, blaze-bin/d1/d2/d3/a_shareddeps.so and
        // blaze-bin/d4/b_shareddeps.so have different path depths. The first could
        // reference a standard blaze-bin/_solib_[arch] via $ORIGIN/../../../_solib[arch],
        // and the second could use $ORIGIN/../_solib_[arch]. But since this is a shared
        // artifact, both are symlinks to the same place, so
        // there's no *one* RPATH setting that fits all targets involved in the sharing.
        rpathRoot = toolchain.getSolibDirectory() + "/";
        if (runtimeRpath) {
          runtimeRpathRoots.add("../" + runtimeSolibName + "/");
        }
      } else {
        // For all other links, calculate the relative path from the output file to _solib_[arch]
        // (the directory where all shared libraries are stored, which resides under the blaze-bin
        // directory. In other words, given blaze-bin/my/package/binary, rpathRoot would be
        // "../../_solib_[arch]".
        if (runtimeRpath) {
          runtimeRpathRoots.add(
              Strings.repeat("../", output.getRootRelativePath().segmentCount() - 1)
                  + runtimeSolibName
                  + "/");
        }

        rpathRoot =
            Strings.repeat("../", output.getRootRelativePath().segmentCount() - 1)
                + toolchain.getSolibDirectory()
                + "/";

        if (isNativeDeps) {
          // We also retain the $ORIGIN/ path to solibs that are in _solib_<arch>, as opposed to
          // the package directory)
          if (runtimeRpath) {
            runtimeRpathRoots.add("../" + runtimeSolibName + "/");
          }
        }
      }

      Map<Artifact, Artifact> ltoMap = generateLtoMap();
      boolean includeSolibDir =
          addLinkerInputs(
              librarySearchDirectories,
              rpathRootsForExplicitSoDeps,
              librariesToLink,
              solibDir,
              rpathRoot,
              ltoMap);
      boolean includeRuntimeSolibDir =
          addRuntimeLinkerInputs(
              librarySearchDirectories,
              rpathRootsForExplicitSoDeps,
              librariesToLink,
              solibDir,
              rpathRoot,
              ltoMap);
      Preconditions.checkState(
          ltoMap == null || ltoMap.isEmpty(), "Still have LTO objects left: %s", ltoMap);

      ImmutableSet.Builder<String> runtimeLibrarySearchDirectories = ImmutableSet.builder();
      // rpath ordering matters for performance; first add the one where most libraries are found.
      if (includeSolibDir) {
        runtimeLibrarySearchDirectories.add(rpathRoot);
      }
      runtimeLibrarySearchDirectories.addAll(rpathRootsForExplicitSoDeps.build());
      if (includeRuntimeSolibDir) {
        runtimeLibrarySearchDirectories.addAll(runtimeRpathRoots.build());
      }

      linkArgCollector.setLibrarySearchDirectories(librarySearchDirectories.build());
      linkArgCollector.setRuntimeLibrarySearchDirectories(runtimeLibrarySearchDirectories.build());
      linkArgCollector.setLibrariesToLink(librariesToLink);
    }

    private Map<Artifact, Artifact> generateLtoMap() {
      if (isLtoIndexing || allLtoArtifacts == null) {
        return null;
      }
      // TODO(bazel-team): The LTO final link can only work if there are individual .o files on
      // the command line. Rather than crashing, this should issue a nice error. We will get
      // this by
      // 1) moving supports_start_end_lib to a toolchain feature
      // 2) having thin_lto require start_end_lib
      // As a bonus, we can rephrase --nostart_end_lib as --features=-start_end_lib and get rid
      // of a command line option.

      Preconditions.checkState(cppConfiguration.useStartEndLib());
      Map<Artifact, Artifact> ltoMap = new HashMap<>();
      for (LtoBackendArtifacts l : allLtoArtifacts) {
        ltoMap.put(l.getBitcodeFile(), l.getObjectFile());
      }
      return ltoMap;
    }

    private boolean addRuntimeLinkerInputs(
        Builder<String> librarySearchDirectories,
        Builder<String> rpathRootsForExplicitSoDeps,
        SequenceBuilder librariesToLink,
        PathFragment solibDir,
        String rpathRoot,
        Map<Artifact, Artifact> ltoMap) {
      boolean includeRuntimeSolibDir = false;
      for (LinkerInput input : runtimeLinkerInputs) {
        if (input.getArtifactCategory() == ArtifactCategory.DYNAMIC_LIBRARY) {
          PathFragment libDir = input.getArtifact().getExecPath().getParentDirectory();
          Preconditions.checkState(
              runtimeSolibDir != null && libDir.equals(runtimeSolibDir),
              "Artifact '%s' is not under directory '%s'.",
              input.getArtifact(),
              solibDir);
          includeRuntimeSolibDir = true;
          addDynamicInputLinkOptions(
              input,
              librariesToLink,
              librarySearchDirectories,
              rpathRootsForExplicitSoDeps,
              solibDir,
              rpathRoot);
        } else {
          addStaticInputLinkOptions(input, librariesToLink, true, ltoMap);
        }
      }
      return includeRuntimeSolibDir;
    }

    private boolean addLinkerInputs(
        Builder<String> librarySearchDirectories,
        Builder<String> rpathEntries,
        SequenceBuilder librariesToLink,
        PathFragment solibDir,
        String rpathRoot,
        Map<Artifact, Artifact> ltoMap) {
      boolean includeSolibDir = false;
      for (LinkerInput input : linkerInputs) {
        if (input.getArtifactCategory() == ArtifactCategory.DYNAMIC_LIBRARY) {
          PathFragment libDir = input.getArtifact().getExecPath().getParentDirectory();
          // When COPY_DYNAMIC_LIBRARIES_TO_BINARY is enabled, dynamic libraries are not symlinked
          // under solibDir, so don't check it.
          if (!featureConfiguration.isEnabled(CppRuleClasses.COPY_DYNAMIC_LIBRARIES_TO_BINARY)) {
            Preconditions.checkState(
                libDir.startsWith(solibDir),
                "Artifact '%s' is not under directory '%s'.",
                input.getArtifact(),
                solibDir);
          }
          if (libDir.equals(solibDir)) {
            includeSolibDir = true;
          }
          addDynamicInputLinkOptions(
              input,
              librariesToLink,
              librarySearchDirectories,
              rpathEntries,
              solibDir,
              rpathRoot);
        } else {
          addStaticInputLinkOptions(input, librariesToLink, false, ltoMap);
        }
      }
      return includeSolibDir;
    }

    /**
     * Adds command-line options for a dynamic library input file into options and libOpts.
     *
     * @param librariesToLink - a collection that will be exposed as a build variable.
     */
    private void addDynamicInputLinkOptions(
        LinkerInput input,
        SequenceBuilder librariesToLink,
        ImmutableSet.Builder<String> librarySearchDirectories,
        ImmutableSet.Builder<String> rpathRootsForExplicitSoDeps,
        PathFragment solibDir,
        String rpathRoot) {
      Preconditions.checkState(input.getArtifactCategory() == ArtifactCategory.DYNAMIC_LIBRARY);
      Preconditions.checkState(!Link.useStartEndLib(input, cppConfiguration.archiveType()));

      Artifact inputArtifact = input.getArtifact();
      PathFragment libDir = inputArtifact.getExecPath().getParentDirectory();
      if (!libDir.equals(solibDir)
          && (runtimeSolibDir == null || !runtimeSolibDir.equals(libDir))) {
        String dotdots = "";
        PathFragment commonParent = solibDir;
        while (!libDir.startsWith(commonParent)) {
          dotdots += "../";
          commonParent = commonParent.getParentDirectory();
        }

        rpathRootsForExplicitSoDeps.add(
            rpathRoot + dotdots + libDir.relativeTo(commonParent).getPathString());
      }

      librarySearchDirectories.add(
          inputArtifact.getExecPath().getParentDirectory().getPathString());

      String name = inputArtifact.getFilename();
      if (CppFileTypes.SHARED_LIBRARY.matches(name)) {
        // Use normal shared library resolution rules for shared libraries.
        String libName = name.replaceAll("(^lib|\\.(so|dylib)$)", "");
        librariesToLink.addValue(
            LibraryToLinkValue.forDynamicLibrary(libName));
      } else if (CppFileTypes.VERSIONED_SHARED_LIBRARY.matches(name)) {
        // Versioned shared libraries require the exact library filename, e.g.:
        // -lfoo -> libfoo.so
        // -l:libfoo.so.1 -> libfoo.so.1
        librariesToLink.addValue(
            LibraryToLinkValue.forVersionedDynamicLibrary(name));
      } else {
        // Interface shared objects have a non-standard extension
        // that the linker won't be able to find.  So use the
        // filename directly rather than a -l option.  Since the
        // library has an SONAME attribute, this will work fine.
        librariesToLink.addValue(
            LibraryToLinkValue.forInterfaceLibrary(inputArtifact.getExecPathString()));
      }
    }

    /**
     * Adds command-line options for a static library or non-library input into options.
     *
     * @param librariesToLink - a collection that will be exposed as a build variable.
     * @param ltoMap is a mutable list of exec paths that should be on the command-line, which must
     */
    private void addStaticInputLinkOptions(
        LinkerInput input,
        SequenceBuilder librariesToLink,
        boolean isRuntimeLinkerInput,
        @Nullable Map<Artifact, Artifact> ltoMap) {
      ArtifactCategory artifactCategory = input.getArtifactCategory();
      Preconditions.checkState(artifactCategory != ArtifactCategory.DYNAMIC_LIBRARY);
      // If we had any LTO artifacts, ltoMap whould be non-null. In that case,
      // we should have created a thinltoParamFile which the LTO indexing
      // step will populate with the exec paths that correspond to the LTO
      // artifacts that the linker decided to include based on symbol resolution.
      // Those files will be included directly in the link (and not wrapped
      // in --start-lib/--end-lib) to ensure consistency between the two link
      // steps.
      Preconditions.checkState(ltoMap == null || thinltoParamFile != null);

      // start-lib/end-lib library: adds its input object files.
      if (Link.useStartEndLib(input, cppConfiguration.archiveType())) {
        Iterable<Artifact> archiveMembers = input.getObjectFiles();
        if (!Iterables.isEmpty(archiveMembers)) {
          ImmutableList.Builder<String> nonLtoArchiveMembersBuilder = ImmutableList.builder();
          for (Artifact member : archiveMembers) {
            if (ltoMap != null && ltoMap.remove(member) != null) {
              // The LTO artifacts that should be included in the final link
              // are listed in the thinltoParamFile. When ltoMap is non-null
              // the backend artifact may be missing due to libraries that list .o
              // files explicitly, or generate .o files from assembler.
              continue;
            }
            nonLtoArchiveMembersBuilder.add(member.getExecPathString());
          }
          ImmutableList<String> nonLtoArchiveMembers = nonLtoArchiveMembersBuilder.build();
          if (!nonLtoArchiveMembers.isEmpty()) {
            boolean inputIsWholeArchive = !isRuntimeLinkerInput && needWholeArchive;
            librariesToLink.addValue(
                LibraryToLinkValue.forObjectFileGroup(nonLtoArchiveMembers, inputIsWholeArchive));
          }
        }
      } else {
        Preconditions.checkArgument(
            artifactCategory.equals(ArtifactCategory.OBJECT_FILE)
                || artifactCategory.equals(ArtifactCategory.STATIC_LIBRARY)
                || artifactCategory.equals(ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY));
        boolean isAlwaysLinkStaticLibrary =
            artifactCategory == ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY;
        boolean inputIsWholeArchive =
            (!isRuntimeLinkerInput && (isAlwaysLinkStaticLibrary || needWholeArchive))
                || (isRuntimeLinkerInput && isAlwaysLinkStaticLibrary && !needWholeArchive);

        Artifact inputArtifact = input.getArtifact();
        if (ltoMap != null && ltoMap.remove(inputArtifact) != null) {
          // The LTO artifacts that should be included in the final link
          // are listed in the thinltoParamFile.
          return;
        }

        String name;
        if (input.isFake()) {
          name = Link.FAKE_OBJECT_PREFIX + inputArtifact.getExecPathString();
        } else {
          name = inputArtifact.getExecPathString();
        }

        librariesToLink.addValue(
            artifactCategory.equals(ArtifactCategory.OBJECT_FILE)
                ? LibraryToLinkValue.forObjectFile(name, inputIsWholeArchive)
                : LibraryToLinkValue.forStaticLibrary(name, inputIsWholeArchive));
      }
    }
  }
}
