// Copyright 2020 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 com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static java.util.Arrays.stream;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.util.Crosstool.CcToolchainConfig;
import com.google.devtools.build.lib.packages.util.MockCcSupport;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.RuleConfiguredTargetValue;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.util.List;
import java.util.stream.Stream;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for cc_binary with ThinLTO. */
@RunWith(JUnit4.class)
public class CcBinaryThinLtoTest extends BuildViewTestCase {

  private String targetName = "bin";

  private ConfiguredTarget getCurrentTarget() throws Exception {
    return getConfiguredTarget("//pkg:" + targetName);
  }

  private CppLinkAction getLinkAction() throws Exception {
    ConfiguredTarget pkg = getCurrentTarget();
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);
    return linkAction;
  }

  private LtoBackendAction getBackendAction(String path) throws Exception {
    return (LtoBackendAction) getPredecessorByInputName(getLinkAction(), path);
  }

  private String getRootExecPath() throws Exception {
    ConfiguredTarget pkg = getCurrentTarget();
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    return pkgArtifact.getRoot().getExecPathString();
  }

  private CppLinkAction getIndexAction(LtoBackendAction backendAction) throws Exception {
    return (CppLinkAction)
        getPredecessorByInputName(
            backendAction, backendAction.getPrimaryOutput().getExecPathString() + ".thinlto.bc");
  }

  @Before
  public void createBasePkg() throws IOException {
    scratch.overwriteFile(
        "base/BUILD",
        "cc_library(name = 'system_malloc', visibility = ['//visibility:public'])",
        "cc_library(name = 'empty_lib', visibility = ['//visibility:public'])");
  }

  public void createBuildFiles(String... extraCcBinaryParameters) throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "",
        "cc_binary(name = '" + targetName + "',",
        "          srcs = ['binfile.cc', ],",
        "          deps = [ ':lib' ], ",
        String.join("", extraCcBinaryParameters),
        "          link_extra_lib = '//base:empty_lib', ",
        "          malloc = '//base:system_malloc')",
        "cc_library(name = 'lib',",
        "        srcs = ['libfile.cc'],",
        "        hdrs = ['libfile.h'],",
        "        linkstamp = 'linkstamp.cc',",
        "       )");

    scratch.file("pkg/binfile.cc", "#include \"pkg/libfile.h\"", "int main() { return pkg(); }");
    scratch.file("pkg/libfile.cc", "int pkg() { return 42; }");
    scratch.file("pkg/libfile.h", "int pkg();");
    scratch.file("pkg/linkstamp.cc");
  }

  public void createTestFiles(String extraTestParameters, String extraLibraryParameters)
      throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "cc_test(",
        "    name = 'bin_test',",
        "    srcs = ['bin_test.cc', ],",
        "    deps = [ ':lib' ], ",
        extraTestParameters,
        "    link_extra_lib = '//base:empty_lib', ",
        "    malloc = '//base:system_malloc'",
        ")",
        "cc_test(",
        "    name = 'bin_test2',",
        "    srcs = ['bin_test2.cc', ],",
        "    deps = [ ':lib' ], ",
        extraTestParameters,
        "    link_extra_lib = '//base:empty_lib', ",
        "    malloc = '//base:system_malloc'",
        ")",
        "cc_library(",
        "    name = 'lib',",
        "    srcs = ['libfile.cc'],",
        "    hdrs = ['libfile.h'],",
        extraLibraryParameters,
        "    linkstamp = 'linkstamp.cc',",
        ")");

    scratch.file("pkg/bin_test.cc", "#include \"pkg/libfile.h\"", "int main() { return pkg(); }");
    scratch.file("pkg/bin_test2.cc", "#include \"pkg/libfile.h\"", "int main() { return pkg(); }");
    scratch.file("pkg/libfile.cc", "int pkg() { return 42; }");
    scratch.file("pkg/libfile.h", "int pkg();");
    scratch.file("pkg/linkstamp.cc");
  }

  @Test
  public void testActionGraph() throws Exception {
    createBuildFiles();
    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration("--noincompatible_make_thinlto_command_lines_standalone");

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    {.o.thinlto.bc,.o.imports} <=[LTOIndexing]=
    .o <= [CppCompile] .cc
    */
    ConfiguredTarget pkg = getCurrentTarget();
    CppLinkAction linkAction = getLinkAction();
    String rootExecPath = getRootExecPath();

    assertThat(ActionsTestUtil.getFirstArtifactEndingWith(linkAction.getInputs(), "linkstamp.o"))
        .isNotNull();

    List<String> commandLine = linkAction.getLinkCommandLineForTesting().getRawLinkArgv();
    String prefix = getTargetConfiguration().getOutputDirectory(RepositoryName.MAIN)
        .getExecPathString();
    assertThat(commandLine)
        .containsAtLeast(
            prefix + "/bin/pkg/bin.lto.merged.o",
            "thinlto_param_file=" + prefix + "/bin/pkg/bin-lto-final.params")
        .inOrder();

    // We have no bitcode files: all files have pkg/bin.lto/
    for (String arg : commandLine) {
      if (arg.contains("_objs") && !arg.contains("linkstamp.o")) {
        assertThat(arg).contains("pkg/bin.lto");
      }
    }

    assertThat(artifactsToStrings(linkAction.getInputs()))
        .containsAtLeast(
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o",
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o",
            "bin pkg/bin-2.params",
            "bin pkg/bin-lto-final.params");

    LtoBackendAction backendAction =
        getBackendAction("pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");

    assertThat(artifactsToStrings(backendAction.getInputs()))
        .containsAtLeast(
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o.thinlto.bc",
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o.imports");

    assertThat(backendAction.getArguments())
        .containsAtLeast(
            "thinlto_index="
                + prefix
                + "/bin/pkg/bin.lto/"
                + rootExecPath
                + "/pkg/_objs/bin/binfile.pic.o.thinlto.bc",
            "thinlto_output_object_file="
                + prefix
                + "/bin/pkg/bin.lto/"
                + rootExecPath
                + "/pkg/_objs/bin/binfile.pic.o",
            "thinlto_input_bitcode_file=" + prefix + "/bin/pkg/_objs/bin/binfile.pic.o");

    CppLinkAction indexAction = getIndexAction(backendAction);

    RuleConfiguredTargetValue configuredTargetValue =
        (RuleConfiguredTargetValue)
            getSkyframeExecutor()
                .getEvaluator()
                .getExistingEntryAtCurrentlyEvaluatingVersion(
                    ConfiguredTargetKey.builder()
                        .setLabel(pkg.getLabel())
                        .setConfiguration(getConfiguration(pkg))
                        .build())
                .getValue();
    ImmutableList<ActionAnalysisMetadata> linkstampCompileActions =
        configuredTargetValue.getActions().stream()
            .filter(a -> a.getMnemonic().equals("CppLinkstampCompile"))
            .collect(toImmutableList());
    assertThat(linkstampCompileActions).hasSize(1);
    ActionAnalysisMetadata linkstampCompileAction = linkstampCompileActions.get(0);
    assertThat(indexAction.getInputs().toList())
        .containsNoneIn(linkstampCompileAction.getOutputs());

    assertThat(indexAction.getArguments())
        .containsAtLeast(
            "param_file=" + prefix + "/bin/pkg/bin-lto-final.params",
            "prefix_replace=" + ";" + prefix + "/bin/pkg/bin.lto/",
            "thinlto_merged_object_file=" + prefix + "/bin/pkg/bin.lto.merged.o",
            "object_suffix_replace=.indexing.o;.o");
    assertThat(indexAction.getArguments())
        .doesNotContain("thinlto_param_file=" + prefix + "/bin/pkg/bin-lto-final.params");

    assertThat(artifactsToStrings(indexAction.getOutputs()))
        .containsAtLeast(
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o.imports",
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o.thinlto.bc",
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o.imports",
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o.thinlto.bc",
            "bin pkg/bin-lto-final.params");

    assertThat(indexAction.getMnemonic()).isEqualTo("CppLTOIndexing");

    assertThat(artifactsToStrings(indexAction.getInputs()))
        .containsAtLeast(
            "bin pkg/_objs/bin/binfile.pic.indexing.o", "bin pkg/_objs/lib/libfile.pic.indexing.o");

    CppCompileAction bitcodeAction =
        (CppCompileAction)
            getPredecessorByInputName(indexAction, "pkg/_objs/bin/binfile.pic.indexing.o");
    assertThat(bitcodeAction.getMnemonic()).isEqualTo("CppCompile");
    assertThat(bitcodeAction.getArguments())
        .contains("lto_indexing_bitcode=" + prefix + "/bin/pkg/_objs/bin/binfile.pic.indexing.o");
  }

  @Test
  public void testLinkshared() throws Exception {
    targetName = "bin.so";
    createBuildFiles("linkshared = 1,");
    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration();

    CppLinkAction linkAction = getLinkAction();
    String rootExecPath = getRootExecPath();

    Action backendAction =
        getPredecessorByInputName(
            linkAction, "pkg/bin.so.lto/" + rootExecPath + "/pkg/_objs/bin.so/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
  }

  @Test
  public void testNoLinkstatic() throws Exception {
    createBuildFiles("linkstatic = 0,");
    setupThinLTOCrosstool(
        CppRuleClasses.SUPPORTS_DYNAMIC_LINKER,
        CppRuleClasses.SUPPORTS_PIC,
        CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES);
    useConfiguration("--noincompatible_make_thinlto_command_lines_standalone");

    /*
    We follow the chain from the final product backwards to verify intermediate actions.

    binary <=[Link]=
    .ifso <=[SolibSymlink]=
    _S...ifso <=[SolibSymlink]=
    .ifso <=[Link]=
    .lto/...o <=[LTOBackend]=
    {.o.thinlto.bc,.o.imports} <=[LTOIndexing]=
    .o <= [CppCompile] .cc
    */
    CppLinkAction linkAction = getLinkAction();
    String rootExecPath = getRootExecPath();

    List<String> commandLine = linkAction.getLinkCommandLineForTesting().getRawLinkArgv();
    String prefix = getTargetConfiguration().getOutputDirectory(RepositoryName.MAIN)
        .getExecPathString();

    assertThat(commandLine).contains("-Wl,@" + prefix + "/bin/pkg/bin-lto-final.params");

    // We have no bitcode files: all files have pkg/bin.lto/
    for (String arg : commandLine) {
      if (arg.contains("_objs") && !arg.contains("linkstamp.o")) {
        assertThat(arg).contains("pkg/bin.lto");
      }
    }

    assertThat(artifactsToStrings(linkAction.getInputs()))
        .containsAtLeast(
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o",
            "bin _solib_k8/libpkg_Sliblib.ifso",
            "bin pkg/bin-2.params",
            "bin pkg/bin-lto-final.params");

    SolibSymlinkAction solibSymlinkAction =
        (SolibSymlinkAction) getPredecessorByInputName(linkAction, "_solib_k8/libpkg_Sliblib.ifso");
    assertThat(solibSymlinkAction.getMnemonic()).isEqualTo("SolibSymlink");

    CppLinkAction libLinkAction =
        (CppLinkAction) getPredecessorByInputName(solibSymlinkAction, "bin/pkg/liblib.ifso");
    assertThat(libLinkAction.getMnemonic()).isEqualTo("CppLink");

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                libLinkAction,
                "pkg/liblib.so.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");

    assertThat(artifactsToStrings(backendAction.getInputs()))
        .contains(
            "bin pkg/liblib.so.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o.thinlto.bc");

    assertThat(backendAction.getArguments())
        .containsAtLeast(
            "thinlto_index="
                + prefix
                + "/bin/pkg/liblib.so.lto/"
                + rootExecPath
                + "/pkg/_objs/lib/libfile.pic.o.thinlto.bc",
            "thinlto_output_object_file="
                + prefix
                + "/bin/pkg/liblib.so.lto/"
                + rootExecPath
                + "/pkg/_objs/lib/libfile.pic.o",
            "thinlto_input_bitcode_file=" + prefix + "/bin/pkg/_objs/lib/libfile.pic.o");

    CppLinkAction indexAction =
        (CppLinkAction)
            getPredecessorByInputName(
                backendAction,
                "pkg/liblib.so.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o.thinlto.bc");

    assertThat(indexAction.getArguments())
        .containsAtLeast(
            "param_file=" + prefix + "/bin/pkg/liblib.so-lto-final.params",
            "prefix_replace=" + ";" + prefix + "/bin/pkg/liblib.so.lto/",
            "object_suffix_replace=.indexing.o;.o");

    assertThat(artifactsToStrings(indexAction.getOutputs()))
        .containsAtLeast(
            "bin pkg/liblib.so.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o.imports",
            "bin pkg/liblib.so.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o.thinlto.bc",
            "bin pkg/liblib.so-lto-final.params");

    assertThat(indexAction.getMnemonic()).isEqualTo("CppLTOIndexing");

    assertThat(artifactsToStrings(indexAction.getInputs()))
        .contains("bin pkg/_objs/lib/libfile.pic.indexing.o");

    CppCompileAction bitcodeAction =
        (CppCompileAction)
            getPredecessorByInputName(indexAction, "pkg/_objs/lib/libfile.pic.indexing.o");
    assertThat(bitcodeAction.getMnemonic()).isEqualTo("CppCompile");
    assertThat(bitcodeAction.getArguments())
        .contains("lto_indexing_bitcode=" + prefix + "/bin/pkg/_objs/lib/libfile.pic.indexing.o");
  }

  /** Helper method to get the root prefix from the given dwpFile. */
  private static PathFragment dwpRootPrefix(Artifact dwpFile) throws Exception {
    return dwpFile
        .getExecPath()
        .subFragment(
            0, dwpFile.getExecPath().segmentCount() - dwpFile.getRootRelativePath().segmentCount());
  }

  /** Helper method that checks that a .dwp has the expected generating action structure. */
  private void validateDwp(
      RuleContext ruleContext,
      Artifact dwpFile,
      CcToolchainProvider toolchain,
      List<String> expectedInputs)
      throws Exception {
    SpawnAction dwpAction = (SpawnAction) getGeneratingAction(dwpFile);
    String dwpToolPath = toolchain.getToolPathFragment(Tool.DWP, ruleContext).getPathString();
    assertThat(dwpAction.getMnemonic()).isEqualTo("CcGenerateDwp");
    assertThat(dwpToolPath).isEqualTo(dwpAction.getCommandFilename());
    List<String> commandArgs = dwpAction.getArguments();
    // The first argument should be the command being executed.
    assertThat(dwpToolPath).isEqualTo(commandArgs.get(0));
    // The final two arguments should be "-o dwpOutputFile".
    assertThat(commandArgs.subList(commandArgs.size() - 2, commandArgs.size()))
        .containsExactly("-o", dwpFile.getExecPathString())
        .inOrder();
    // The remaining arguments should be the set of .dwo inputs (in any order).
    assertThat(commandArgs.subList(1, commandArgs.size() - 2))
        .containsExactlyElementsIn(expectedInputs);
  }

  @Test
  public void testFission() throws Exception {
    createBuildFiles();
    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PER_OBJECT_DEBUG_INFO);
    useConfiguration("--fission=yes", "--copt=-g0");

    String rootExecPath = getRootExecPath();
    LtoBackendAction backendAction =
        getBackendAction("pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(artifactsToStrings(backendAction.getOutputs()))
        .containsExactly(
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o",
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.dwo");

    assertThat(backendAction.getArguments()).containsAtLeast("-g0", "per_object_debug_info_option");

    backendAction =
        getBackendAction("pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(artifactsToStrings(backendAction.getOutputs()))
        .containsExactly(
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o",
            "bin pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.dwo");

    assertThat(backendAction.getArguments()).contains("per_object_debug_info_option");

    // Now check the dwp action.
    ConfiguredTarget pkg = getCurrentTarget();
    Artifact dwpFile = getFileConfiguredTarget(pkg.getLabel() + ".dwp").getArtifact();
    PathFragment rootPrefix = dwpRootPrefix(dwpFile);
    RuleContext ruleContext = getRuleContext(pkg);
    CcToolchainProvider toolchain =
        CppHelper.getToolchainUsingDefaultCcToolchainAttribute(ruleContext);
    validateDwp(
        ruleContext,
        dwpFile,
        toolchain,
        ImmutableList.of(
            rootPrefix + "/pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.dwo",
            rootPrefix + "/pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.dwo"));
  }

  @Test
  public void testNoLinkstaticFission() throws Exception {
    createBuildFiles("linkstatic = 0,");
    setupThinLTOCrosstool(
        CppRuleClasses.SUPPORTS_PIC,
        CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES,
        CppRuleClasses.SUPPORTS_DYNAMIC_LINKER,
        CppRuleClasses.PER_OBJECT_DEBUG_INFO);
    useConfiguration("--fission=yes");

    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    SolibSymlinkAction solibSymlinkAction =
        (SolibSymlinkAction) getPredecessorByInputName(linkAction, "_solib_k8/libpkg_Sliblib.ifso");
    assertThat(solibSymlinkAction.getMnemonic()).isEqualTo("SolibSymlink");

    CppLinkAction libLinkAction =
        (CppLinkAction) getPredecessorByInputName(solibSymlinkAction, "bin/pkg/liblib.ifso");
    assertThat(libLinkAction.getMnemonic()).isEqualTo("CppLink");

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                libLinkAction,
                "pkg/liblib.so.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(artifactsToStrings(backendAction.getOutputs()))
        .containsExactly(
            "bin pkg/liblib.so.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o",
            "bin pkg/liblib.so.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.dwo");

    assertThat(backendAction.getArguments()).contains("per_object_debug_info_option");

    // Check the dwp action.
    Artifact dwpFile = getFileConfiguredTarget(pkg.getLabel() + ".dwp").getArtifact();
    PathFragment rootPrefix = dwpRootPrefix(dwpFile);
    RuleContext ruleContext = getRuleContext(pkg);
    CcToolchainProvider toolchain =
        CppHelper.getToolchainUsingDefaultCcToolchainAttribute(ruleContext);
    validateDwp(
        ruleContext,
        dwpFile,
        toolchain,
        ImmutableList.of(
            rootPrefix + "/pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.dwo"));
  }

  @Test
  public void testLinkstaticCcTestFission() throws Exception {
    createTestFiles("linkstatic = 1,", "");

    setupThinLTOCrosstool(
        CppRuleClasses.SUPPORTS_PIC,
        CppRuleClasses.THIN_LTO_LINKSTATIC_TESTS_USE_SHARED_NONLTO_BACKENDS,
        CppRuleClasses.PER_OBJECT_DEBUG_INFO);
    useConfiguration(
        "--fission=yes", "--features=thin_lto_linkstatic_tests_use_shared_nonlto_backends");

    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin_test");
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);

    // All backends should be shared non-LTO in this case
    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "shared.nonlto/" + rootExecPath + "/pkg/_objs/bin_test/bin_test.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(artifactsToStrings(backendAction.getOutputs()))
        .containsExactly(
            "bin shared.nonlto/" + rootExecPath + "/pkg/_objs/bin_test/bin_test.pic.o",
            "bin shared.nonlto/" + rootExecPath + "/pkg/_objs/bin_test/bin_test.pic.dwo");

    assertThat(backendAction.getArguments()).contains("per_object_debug_info_option");

    backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "shared.nonlto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(backendAction.getArguments()).contains("-fPIC");
    assertThat(artifactsToStrings(backendAction.getOutputs()))
        .containsExactly(
            "bin shared.nonlto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o",
            "bin shared.nonlto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.dwo");

    assertThat(backendAction.getArguments()).contains("per_object_debug_info_option");

    // Now check the dwp action.
    Artifact dwpFile = getFileConfiguredTarget(pkg.getLabel() + ".dwp").getArtifact();
    PathFragment rootPrefix = dwpRootPrefix(dwpFile);
    RuleContext ruleContext = getRuleContext(pkg);
    CcToolchainProvider toolchain =
        CppHelper.getToolchainUsingDefaultCcToolchainAttribute(ruleContext);
    validateDwp(
        ruleContext,
        dwpFile,
        toolchain,
        ImmutableList.of(
            rootPrefix + "/shared.nonlto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.dwo",
            rootPrefix
                + "/shared.nonlto/"
                + rootExecPath
                + "/pkg/_objs/bin_test/bin_test.pic.dwo"));
  }

  @Test
  public void testLinkstaticCcTest() throws Exception {
    createTestFiles("linkstatic = 1,", "");

    setupThinLTOCrosstool(
        CppRuleClasses.SUPPORTS_PIC,
        CppRuleClasses.THIN_LTO_LINKSTATIC_TESTS_USE_SHARED_NONLTO_BACKENDS,
        CppRuleClasses.PER_OBJECT_DEBUG_INFO);
    useConfiguration("--features=thin_lto_linkstatic_tests_use_shared_nonlto_backends");

    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin_test");
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);

    ConfiguredTarget pkg2 = getConfiguredTarget("//pkg:bin_test2");
    Artifact pkgArtifact2 = getFilesToBuild(pkg2).getSingleton();
    CppLinkAction linkAction2 = (CppLinkAction) getGeneratingAction(pkgArtifact2);

    // All backends should be shared non-LTO in this case
    String rootExecPath1 = pkgArtifact.getRoot().getExecPathString();
    String rootExecPath2 = pkgArtifact.getRoot().getExecPathString();
    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction,
                "shared.nonlto/" + rootExecPath1 + "/pkg/_objs/bin_test/bin_test.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");

    backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "shared.nonlto/" + rootExecPath1 + "/pkg/_objs/lib/libfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(backendAction.getArguments()).contains("-fPIC");

    LtoBackendAction backendAction2 =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction2, "shared.nonlto/" + rootExecPath2 + "/pkg/_objs/lib/libfile.pic.o");
    assertThat(backendAction2.getMnemonic()).isEqualTo("CcLtoBackendCompile");

    assertThat(backendAction).isEqualTo(backendAction2);
  }

  @Test
  public void testTestOnlyTarget() throws Exception {
    createBuildFiles("testonly = 1,");

    setupThinLTOCrosstool(
        CppRuleClasses.SUPPORTS_PIC,
        CppRuleClasses.THIN_LTO_LINKSTATIC_TESTS_USE_SHARED_NONLTO_BACKENDS);
    useConfiguration("--features=thin_lto_linkstatic_tests_use_shared_nonlto_backends");

    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();
    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "shared.nonlto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
  }

  @Test
  public void testUseSharedAllLinkstatic() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(
        CppRuleClasses.THIN_LTO_ALL_LINKSTATIC_USE_SHARED_NONLTO_BACKENDS,
        CppRuleClasses.SUPPORTS_PIC);
    useConfiguration("--features=thin_lto_all_linkstatic_use_shared_nonlto_backends");

    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "shared.nonlto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
  }

  private Action getPredecessorByInputName(Action action, String str) {
    for (Artifact a : action.getInputs().toList()) {
      if (a.getExecPathString().contains(str)) {
        return getGeneratingAction(a);
      }
    }
    return null;
  }

  @Test
  public void testAssemblerSource() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          deps = [ ':lib' ], ",
        "          malloc = '//base:system_malloc')",
        "cc_library(name = 'lib',",
        "        srcs = ['tracing.cc', 'tracing_x86-64.S'],",
        "       )");

    scratch.file("pkg/binfile.cc", "int main() { return pkg(); }");
    scratch.file("pkg/tracing.cc", "// hello");
    scratch.file("pkg/tracing_x86-64.S", "NOP");

    setupThinLTOCrosstool();
    useConfiguration();

    ConfiguredTarget bin = getConfiguredTarget("//pkg:bin");

    Artifact binArtifact = getFilesToBuild(bin).getSingleton();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    Action dataGen = getPredecessorByInputName(linkAction, "tracing_x86-64");
    assertWithMessage(linkAction.getInputs().toString()).that(dataGen).isNotNull();
    assertThat(dataGen.getMnemonic()).isEqualTo("CppCompile");
  }

  // Make sure we don't choke on a cc_library without sources and therefore, without bitcode files.
  @Test
  public void testNoSourceFiles() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          deps = [ ':lib' ], ",
        "          malloc = '//base:system_malloc')",
        "cc_library(name = 'lib',",
        "        srcs = ['static.a'],",
        "       )");

    scratch.file("pkg/binfile.cc", "int main() { return 1; }");
    scratch.file("pkg/static.a", "xyz");
    setupThinLTOCrosstool();
    useConfiguration();

    getConfiguredTarget("//pkg:bin");
  }

  @Test
  public void testFdoInstrument() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.FDO_INSTRUMENT);
    useConfiguration("--fdo_instrument=profiles");

    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");

    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    // If the LtoBackendAction incorrectly tries to add the fdo_instrument
    // feature, we will fail with an "unknown variable 'fdo_instrument_path'"
    // error. But let's also explicitly confirm that the fdo_instrument
    // option didn't end up here.
    assertThat(backendAction.getArguments()).doesNotContain("fdo_instrument_option");
  }

  @Test
  public void testLtoIndexOpt() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration(
        "--ltoindexopt=anltoindexopt", "--noincompatible_make_thinlto_command_lines_standalone");

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    {.o.thinlto.bc,.o.imports} <=[LTOIndexing]=
    .o <= [CppCompile] .cc
    */
    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");

    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");

    CppLinkAction indexAction =
        (CppLinkAction)
            getPredecessorByInputName(
                backendAction,
                "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o.thinlto.bc");

    assertThat(indexAction.getArguments()).contains("anltoindexopt");
  }

  @Test
  public void testLtoStandaloneCommandLines() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration(
        "--ltoindexopt=anltoindexopt",
        "--incompatible_make_thinlto_command_lines_standalone",
        "--features=thin_lto");

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    {.o.thinlto.bc,.o.imports} <=[LTOIndexing]=
    .o <= [CppCompile] .cc
    */
    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");

    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");

    CppLinkAction indexAction =
        (CppLinkAction)
            getPredecessorByInputName(
                backendAction,
                "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o.thinlto.bc");

    assertThat(indexAction.getArguments())
        .contains("--i_come_from_standalone_lto_index=anltoindexopt");
  }

  @Test
  public void testCopt() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration("--copt=acopt");

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    */
    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");

    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(backendAction.getArguments()).contains("acopt");
  }

  @Test
  public void testPerFileCopt() throws Exception {
    createBuildFiles();
    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration(
        "--per_file_copt=binfile\\.cc@copt1",
        "--per_file_copt=libfile\\.cc@copt2",
        "--per_file_copt=.*\\.cc,-binfile\\.cc@copt2");

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    */
    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getArguments()).contains("copt1");
    assertThat(backendAction.getArguments()).doesNotContain("copt2");

    backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o");
    assertThat(backendAction.getArguments()).doesNotContain("copt1");
    assertThat(backendAction.getArguments()).contains("copt2");
  }

  @Test
  public void testCoptNoCoptAttributes() throws Exception {
    createBuildFiles("copts = ['acopt', 'nocopt1'], nocopts = 'nocopt1|nocopt2',");

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration("--copt=nocopt2", "--noincompatible_disable_nocopts");

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    */
    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");

    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(backendAction.getArguments()).contains("acopt");
    // TODO(b/122303926): Remove when nocopts are removed, or uncomment and fix if not removing.
    // assertThat(backendAction.getArguments()).doesNotContain("nocopt1");
    // assertThat(backendAction.getArguments()).doesNotContain("nocopt2");
  }

  @Test
  public void testLtoBackendOpt() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, MockCcSupport.USER_COMPILE_FLAGS);
    useConfiguration("--ltobackendopt=anltobackendopt");

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    */
    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");

    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(backendAction.getArguments())
        .containsAtLeast("--default-compile-flag", "anltobackendopt");
  }

  @Test
  public void testPerFileLtoBackendOpt() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration(
        "--per_file_ltobackendopt=binfile\\.pic\\.o@ltobackendopt1",
        "--per_file_ltobackendopt=.*\\.o,-binfile\\.pic\\.o@ltobackendopt2");

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    */
    ConfiguredTarget pkg = getConfiguredTarget("//pkg:bin");
    Artifact pkgArtifact = getFilesToBuild(pkg).getSingleton();
    String rootExecPath = pkgArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(pkgArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(pkgArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getArguments()).contains("ltobackendopt1");
    assertThat(backendAction.getArguments()).doesNotContain("ltobackendopt2");

    backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/lib/libfile.pic.o");
    assertThat(backendAction.getArguments()).doesNotContain("ltobackendopt1");
    assertThat(backendAction.getArguments()).contains("ltobackendopt2");
  }

  @Test
  public void testNoUseLtoIndexingBitcodeFile() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(
        CppRuleClasses.NO_USE_LTO_INDEXING_BITCODE_FILE, CppRuleClasses.SUPPORTS_PIC);
    useConfiguration("--features=no_use_lto_indexing_bitcode_file");
    String rootExecPath = getRootExecPath();

    /*
    We follow the chain from the final product backwards.

    binary <=[Link]=
    .lto/...o <=[LTOBackend]=
    {.o.thinlto.bc,.o.imports} <=[LTOIndexing]=
    .o <= [CppCompile] .cc
    */
    CppLinkAction indexAction =
        getIndexAction(
            getBackendAction("pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o"));

    assertThat(indexAction.getArguments()).doesNotContain("object_suffix_replace");

    assertThat(artifactsToStrings(indexAction.getInputs()))
        .containsAtLeast("bin pkg/_objs/bin/binfile.pic.o", "bin pkg/_objs/lib/libfile.pic.o");

    CppCompileAction bitcodeAction =
        (CppCompileAction) getPredecessorByInputName(indexAction, "pkg/_objs/bin/binfile.pic.o");
    assertThat(bitcodeAction.getArguments()).doesNotContain("lto_indexing_bitcode=");
  }

  @Test
  public void testAutoFdo() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.afdo", "");

    setupThinLTOCrosstool(CppRuleClasses.AUTOFDO);
    useConfiguration("--fdo_optimize=/pkg/profile.afdo", "--compilation_mode=opt");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");

    // Checks that -fauto-profile is added to the LtoBackendAction.
    assertThat(Joiner.on(" ").join(backendAction.getArguments())).containsMatch(
        "-fauto-profile=[^ ]*/profile.afdo");
    assertThat(ActionsTestUtil.baseArtifactNames(backendAction.getInputs())).contains(
        "profile.afdo");
  }

  private void setupThinLTOCrosstool(String... extraFeatures) throws Exception {
    String[] allFeatures =
        Stream.concat(
                Stream.of(
                    CppRuleClasses.THIN_LTO,
                    CppRuleClasses.SUPPORTS_START_END_LIB,
                    MockCcSupport.HOST_AND_NONHOST_CONFIGURATION_FEATURES),
                stream(extraFeatures))
            .toArray(String[]::new);
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures(allFeatures));
  }

  private void setupAutoFdoThinLtoCrosstool() throws Exception {
    setupThinLTOCrosstool(
        CppRuleClasses.AUTOFDO,
        CppRuleClasses.ENABLE_AFDO_THINLTO,
        CppRuleClasses.AUTOFDO_IMPLICIT_THINLTO);
  }

  /**
   * Tests that ThinLTO is not enabled for AFDO with LLVM without
   * --features=autofdo_implicit_thinlto.
   */
  @Test
  public void testAutoFdoNoImplicitThinLto() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.afdo", "");

    setupAutoFdoThinLtoCrosstool();
    useConfiguration("--fdo_optimize=/pkg/profile.afdo", "--compilation_mode=opt");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /** Tests that --features=autofdo_implicit_thinlto enables ThinLTO for AFDO with LLVM. */
  @Test
  public void testAutoFdoImplicitThinLto() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.afdo", "");

    setupAutoFdoThinLtoCrosstool();
    useConfiguration(
        "--fdo_optimize=/pkg/profile.afdo",
        "--compilation_mode=opt",
        "--features=autofdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // For ThinLTO compilation we should have a non-null backend action
    assertThat(backendAction).isNotNull();
  }

  /**
   * Tests that --features=-thin_lto overrides --features=autofdo_implicit_thinlto and prevents
   * enabling ThinLTO for AFDO with LLVM.
   */
  @Test
  public void testAutoFdoImplicitThinLtoDisabledOption() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.afdo", "");

    setupAutoFdoThinLtoCrosstool();
    useConfiguration(
        "--fdo_optimize=/pkg/profile.afdo",
        "--compilation_mode=opt",
        "--features=autofdo_implicit_thinlto",
        "--features=-thin_lto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /**
   * Tests that features=[-thin_lto] in the build rule overrides --features=autofdo_implicit_thinlto
   * and prevents enabling ThinLTO for AFDO with LLVM.
   */
  @Test
  public void testAutoFdoImplicitThinLtoDisabledRule() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          features = ['-thin_lto'],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.afdo", "");

    setupAutoFdoThinLtoCrosstool();
    useConfiguration(
        "--fdo_optimize=/pkg/profile.afdo",
        "--compilation_mode=opt",
        "--features=autofdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /**
   * Tests that features=[-thin_lto] in the package overrides --features=autofdo_implicit_thinlto
   * and prevents enabling ThinLTO for AFDO with LLVM.
   */
  @Test
  public void testAutoFdoImplicitThinLtoDisabledPackage() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['-thin_lto'])",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.afdo", "");

    setupAutoFdoThinLtoCrosstool();
    useConfiguration(
        "--fdo_optimize=/pkg/profile.afdo",
        "--compilation_mode=opt",
        "--features=autofdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  private void setupFdoThinLtoCrosstool() throws Exception {
    setupThinLTOCrosstool(
        CppRuleClasses.FDO_OPTIMIZE,
        CppRuleClasses.ENABLE_FDO_THINLTO,
        MockCcSupport.FDO_IMPLICIT_THINLTO);
  }

  /**
   * Tests that ThinLTO is not enabled for FDO with LLVM without --features=fdo_implicit_thinlto.
   */
  @Test
  public void testFdoNoImplicitThinLto() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.zip", "");

    setupFdoThinLtoCrosstool();
    useConfiguration("--fdo_optimize=/pkg/profile.zip", "--compilation_mode=opt");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /** Tests that --features=fdo_implicit_thinlto enables ThinLTO for FDO with LLVM. */
  @Test
  public void testFdoImplicitThinLto() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.zip", "");

    setupFdoThinLtoCrosstool();
    useConfiguration(
        "--fdo_optimize=/pkg/profile.zip",
        "--compilation_mode=opt",
        "--features=fdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // For ThinLTO compilation we should have a non-null backend action
    assertThat(backendAction).isNotNull();
  }

  /**
   * Tests that --features=-thin_lto overrides --features=fdo_implicit_thinlto and prevents enabling
   * ThinLTO for FDO with LLVM.
   */
  @Test
  public void testFdoImplicitThinLtoDisabledOption() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.zip", "");

    setupFdoThinLtoCrosstool();
    useConfiguration(
        "--fdo_optimize=/pkg/profile.zip",
        "--compilation_mode=opt",
        "--features=fdo_implicit_thinlto",
        "--features=-thin_lto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /**
   * Tests that features=[-thin_lto] in the build rule overrides --features=fdo_implicit_thinlto and
   * prevents enabling ThinLTO for FDO with LLVM.
   */
  @Test
  public void testFdoImplicitThinLtoDisabledRule() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          features = ['-thin_lto'],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.zip", "");

    setupFdoThinLtoCrosstool();
    useConfiguration(
        "--fdo_optimize=/pkg/profile.zip",
        "--compilation_mode=opt",
        "--features=fdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /**
   * Tests that features=[-thin_lto] in the package overrides --features=fdo_implicit_thinlto and
   * prevents enabling ThinLTO for FDO with LLVM.
   */
  @Test
  public void testFdoImplicitThinLtoDisabledPackage() throws Exception {
    setupThinLTOCrosstool();
    scratch.file(
        "pkg/BUILD",
        "package(features = ['-thin_lto'])",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')");

    scratch.file("pkg/binfile.cc", "int main() {}");
    scratch.file("pkg/profile.zip", "");

    setupFdoThinLtoCrosstool();
    useConfiguration(
        "--fdo_optimize=/pkg/profile.zip",
        "--compilation_mode=opt",
        "--features=fdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  private void setupXBinaryFdoThinLtoCrosstool() throws Exception {
    setupThinLTOCrosstool(
        CppRuleClasses.XBINARYFDO,
        CppRuleClasses.ENABLE_XFDO_THINLTO,
        MockCcSupport.XFDO_IMPLICIT_THINLTO);
  }

  /**
   * Tests that ThinLTO is not enabled for XFDO with LLVM without
   * --features=xbinaryfdo_implicit_thinlto.
   */
  @Test
  public void testXBinaryFdoNoImplicitThinLto() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ])",
        "fdo_profile(name='out.xfdo', profile='profiles.xfdo')");

    scratch.file("pkg/binfile.cc", "int main() {}");

    setupXBinaryFdoThinLtoCrosstool();
    useConfiguration("--xbinary_fdo=//pkg:out.xfdo", "--compilation_mode=opt");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /** Tests that --features=xbinaryfdo_implicit_thinlto enables ThinLTO for XFDO with LLVM. */
  @Test
  public void testXBinaryFdoImplicitThinLto() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ])",
        "fdo_profile(name='out.xfdo', profile='profiles.xfdo')");

    scratch.file("pkg/binfile.cc", "int main() {}");

    setupXBinaryFdoThinLtoCrosstool();
    useConfiguration(
        "--xbinary_fdo=//pkg:out.xfdo",
        "--compilation_mode=opt",
        "--features=xbinaryfdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // For ThinLTO compilation we should have a non-null backend action
    assertThat(backendAction).isNotNull();
  }

  /**
   * Tests that --features=-thin_lto overrides --features=xbinaryfdo_implicit_thinlto and prevents
   * enabling ThinLTO for XFDO with LLVM.
   */
  @Test
  public void testXBinaryFdoImplicitThinLtoDisabledOption() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ])",
        "fdo_profile(name='out.xfdo', profile='profiles.xfdo')");

    scratch.file("pkg/binfile.cc", "int main() {}");

    setupXBinaryFdoThinLtoCrosstool();
    useConfiguration(
        "--xbinary_fdo=//pkg:out.xfdo",
        "--compilation_mode=opt",
        "--features=xbinaryfdo_implicit_thinlto",
        "--features=-thin_lto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /**
   * Tests that features=[-thin_lto] in the build rule overrides
   * --features=xbinaryfdo_implicit_thinlto and prevents enabling ThinLTO for XFDO with LLVM.
   */
  @Test
  public void testXBinaryFdoImplicitThinLtoDisabledRule() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          features = ['-thin_lto'])",
        "fdo_profile(name='out.xfdo', profile='profiles.xfdo')");

    scratch.file("pkg/binfile.cc", "int main() {}");

    setupXBinaryFdoThinLtoCrosstool();
    useConfiguration(
        "--xbinary_fdo=//pkg:out.xfdo",
        "--compilation_mode=opt",
        "--features=xbinaryfdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  /**
   * Tests that features=[-thin_lto] in the package overrides --features=fdo_implicit_thinlto and
   * prevents enabling ThinLTO for XFDO with LLVM.
   */
  @Test
  public void testXBinaryFdoImplicitThinLtoDisabledPackage() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['-thin_lto'])",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ])",
        "fdo_profile(name='out.xfdo', profile='profiles.xfdo')");

    scratch.file("pkg/binfile.cc", "int main() {}");

    setupXBinaryFdoThinLtoCrosstool();
    useConfiguration(
        "--xbinary_fdo=//pkg:out.xfdo",
        "--compilation_mode=opt",
        "--features=xbinaryfdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  @Test
  public void testXBinaryFdo() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')",
        "fdo_profile(name='out.xfdo', profile='profiles.xfdo')");

    scratch.file("pkg/binfile.cc", "int main() {}");

    setupThinLTOCrosstool(CppRuleClasses.XBINARYFDO);
    useConfiguration("--xbinary_fdo=//pkg:out.xfdo", "--compilation_mode=opt");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");

    // Checks that -fauto-profile is added to the LtoBackendAction.
    assertThat(Joiner.on(" ").join(backendAction.getArguments()))
        .containsMatch("-fauto-profile=[^ ]*/profiles.xfdo");
    assertThat(ActionsTestUtil.baseArtifactNames(backendAction.getInputs()))
        .contains("profiles.xfdo");
  }

  /**
   * Tests that ThinLTO is not enabled for XBINARYFDO with --features=autofdo_implicit_thinlto and
   * --features=fdo_implicit_thinlto.
   */
  @Test
  public void testXBinaryFdoNoAutoFdoOrFdoImplicitThinLto() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "",
        "cc_binary(name = 'bin',",
        "          srcs = ['binfile.cc', ],",
        "          malloc = '//base:system_malloc')",
        "fdo_profile(name='out.xfdo', profile='profiles.xfdo')");

    scratch.file("pkg/binfile.cc", "int main() {}");

    setupThinLTOCrosstool(
        CppRuleClasses.ENABLE_FDO_THINLTO,
        MockCcSupport.FDO_IMPLICIT_THINLTO,
        CppRuleClasses.ENABLE_AFDO_THINLTO,
        MockCcSupport.AUTOFDO_IMPLICIT_THINLTO,
        CppRuleClasses.XBINARYFDO);
    useConfiguration(
        "--xbinary_fdo=//pkg:out.xfdo",
        "--compilation_mode=opt",
        "--features=autofdo_implicit_thinlto",
        "--features=fdo_implicit_thinlto");

    Artifact binArtifact = getFilesToBuild(getConfiguredTarget("//pkg:bin")).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/pkg/binfile.o");
    // We should not have a ThinLTO backend action
    assertThat(backendAction).isNull();
  }

  @Test
  public void testPICBackendOrder() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC);
    useConfiguration("--copt=-fno-PIE");
    String rootExecPath = getRootExecPath();
    LtoBackendAction backendAction =
        getBackendAction("pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.pic.o");
    assertThat(backendAction.getMnemonic()).isEqualTo("CcLtoBackendCompile");
    assertThat(backendAction.getArguments()).containsAtLeast("-fno-PIE", "-fPIC").inOrder();
  }

  @Test
  public void testPropellerOptimizeAbsoluteOptions() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.AUTOFDO);

    useConfiguration(
        "--propeller_optimize_absolute_cc_profile=/tmp/cc_profile.txt",
        "--propeller_optimize_absolute_ld_profile=/tmp/ld_profile.txt",
        "--compilation_mode=opt");
    Artifact binArtifact = getFilesToBuild(getCurrentTarget()).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);
    assertThat(ActionsTestUtil.baseArtifactNames(linkAction.getInputs()))
        .contains("ld_profile.txt");

    List<String> commandLine = linkAction.getLinkCommandLineForTesting().getRawLinkArgv();
    assertThat(commandLine.toString())
        .containsMatch("-Wl,--symbol-ordering-file=.*/ld_profile.txt");

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");

    String expectedCompilerFlag = "-fbasic-block-sections=list=.*/cc_profile.txt";
    assertThat(Joiner.on(" ").join(backendAction.getArguments()))
        .containsMatch(expectedCompilerFlag);
    String expectedBuildTypeFlag = "-DBUILD_PROPELLER_TYPE=\"full\"";
    assertThat(Joiner.on(" ").join(backendAction.getArguments()))
        .containsMatch(expectedBuildTypeFlag);
    assertThat(ActionsTestUtil.baseArtifactNames(backendAction.getInputs()))
        .contains("cc_profile.txt");

    CppLinkAction indexAction = getIndexAction(backendAction);
    assertThat(ActionsTestUtil.baseArtifactNames(indexAction.getInputs()))
        .doesNotContain("ld_profile.txt");
  }

  @Test
  public void testPropellerCcCompile() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.AUTOFDO);

    useConfiguration(
        "--propeller_optimize_absolute_cc_profile=/tmp/cc_profile.txt",
        "--propeller_optimize_absolute_ld_profile=/tmp/ld_profile.txt",
        "--compilation_mode=opt");
    Artifact binArtifact = getFilesToBuild(getCurrentTarget()).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    CppLinkAction indexAction = getIndexAction(backendAction);
    CppCompileAction bitcodeAction =
        (CppCompileAction)
            getPredecessorByInputName(indexAction, "pkg/_objs/bin/binfile.indexing.o");
    assertThat(ActionsTestUtil.baseArtifactNames(bitcodeAction.getInputs()))
        .doesNotContain("cc_profile.txt");
    assertThat(Joiner.on(" ").join(bitcodeAction.getArguments()))
        .doesNotContainMatch("-fbasic-block-sections=");
  }

  /**
   * Check that the temporary opt-out from disabling Propeller profiles for ThinLTO compile actions
   * works.
   *
   * <p>TODO(b/182804945): Remove after making sure that the rollout of the new Propeller profile
   * passing logic didn't break anything.
   */
  @Test
  public void testPropellerCcCompileWithPropellerOptimizeThinLtoCompileActions() throws Exception {
    createBuildFiles();

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.AUTOFDO);

    useConfiguration(
        "--propeller_optimize_absolute_cc_profile=/tmp/cc_profile.txt",
        "--propeller_optimize_absolute_ld_profile=/tmp/ld_profile.txt",
        "--compilation_mode=opt",
        "--features=propeller_optimize_thinlto_compile_actions");
    Artifact binArtifact = getFilesToBuild(getCurrentTarget()).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    CppLinkAction indexAction = getIndexAction(backendAction);
    assertThat(artifactsToStrings(indexAction.getInputs()))
        .containsAtLeast(
            "bin pkg/_objs/bin/binfile.indexing.o", "bin pkg/_objs/lib/libfile.indexing.o");

    CppCompileAction bitcodeAction =
        (CppCompileAction)
            getPredecessorByInputName(indexAction, "pkg/_objs/bin/binfile.indexing.o");
    assertThat(ActionsTestUtil.baseArtifactNames(bitcodeAction.getInputs()))
        .contains("cc_profile.txt");
    assertThat(Joiner.on(" ").join(bitcodeAction.getArguments()))
        .containsMatch("-fbasic-block-sections=list=.*/cc_profile.txt");
  }

  @Test
  public void testPropellerCcCompileWithThinLtoDisabled() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "",
        "cc_binary(name = '" + targetName + "',",
        "          srcs = ['binfile.cc', ],",
        "          deps = [ ':lib' ], ",
        "          malloc = '//base:system_malloc')",
        "cc_library(name = 'lib',",
        "        srcs = ['libfile.cc'],",
        "        hdrs = ['libfile.h'],",
        "        linkstamp = 'linkstamp.cc',",
        "        features = ['-thin_lto'],",
        "       )");

    scratch.file("pkg/binfile.cc", "#include \"pkg/libfile.h\"", "int main() { return pkg(); }");
    scratch.file("pkg/libfile.cc", "int pkg() { return 42; }");
    scratch.file("pkg/libfile.h", "int pkg();");
    scratch.file("pkg/linkstamp.cc");

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.AUTOFDO);

    useConfiguration(
        "--propeller_optimize_absolute_cc_profile=/tmp/cc_profile.txt",
        "--propeller_optimize_absolute_ld_profile=/tmp/ld_profile.txt",
        "--compilation_mode=opt");
    Artifact binArtifact = getFilesToBuild(getCurrentTarget()).getSingleton();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    CppCompileAction compileAction =
        (CppCompileAction) getPredecessorByInputName(linkAction, "pkg/_objs/lib/libfile.o");
    assertThat(ActionsTestUtil.baseArtifactNames(compileAction.getInputs()))
        .contains("cc_profile.txt");
    assertThat(Joiner.on(" ").join(compileAction.getArguments()))
        .containsMatch("-fbasic-block-sections=list=.*/cc_profile.txt");
  }

  @Test
  public void testPropellerHostBuilds() throws Exception {
    scratch.file(
        "pkg/BUILD",
        "package(features = ['thin_lto'])",
        "",
        "cc_binary(name = '" + targetName + "',",
        "          srcs = ['binfile.cc', ],",
        "          deps = [ ':lib' ], ",
        "          malloc = '//base:system_malloc')",
        "cc_library(name = 'lib',",
        "        srcs = ['libfile.cc'],",
        "        hdrs = ['libfile.h'])",
        "cc_binary(name = 'gen_lib',",
        "        srcs = ['gen_lib.cc'])",
        "genrule(name = 'lib_genrule',",
        "        srcs = [],",
        "        outs = ['libfile.cc'],",
        "        cmd = '$(location gen_lib) > \"$@\"',",
        "        tools = [':gen_lib'])");

    scratch.file("pkg/binfile.cc", "#include \"pkg/libfile.h\"", "int main() { return pkg(); }");
    scratch.file(
        "pkg/gen_lib.cc",
        "#include <cstdio>",
        "int main() { puts(\"int pkg() { return 42; }\"); }");
    scratch.file("pkg/libfile.h", "int pkg();");

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.AUTOFDO);

    useConfiguration(
        "--propeller_optimize_absolute_cc_profile=/tmp/cc_profile.txt",
        "--propeller_optimize_absolute_ld_profile=/tmp/ld_profile.txt",
        "--compilation_mode=opt");
    Artifact binArtifact = getFilesToBuild(getCurrentTarget()).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();
    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");
    CppLinkAction indexAction = getIndexAction(backendAction);
    assertThat(artifactsToStrings(indexAction.getInputs()))
        .contains("bin pkg/_objs/lib/libfile.indexing.o");

    CppCompileAction bitcodeAction =
        (CppCompileAction)
            getPredecessorByInputName(indexAction, "pkg/_objs/lib/libfile.indexing.o");

    Action genruleAction = getPredecessorByInputName(bitcodeAction, "pkg/libfile.cc");

    CppLinkAction hostLinkAction =
        (CppLinkAction) getPredecessorByInputName(genruleAction, "pkg/gen_lib");
    assertThat(ActionsTestUtil.baseArtifactNames(hostLinkAction.getInputs()))
        .doesNotContain("ld_profile.txt");
    assertThat(hostLinkAction.getLinkCommandLineForTesting().getRawLinkArgv().toString())
        .doesNotContainMatch("-Wl,--symbol-ordering-file=.*/ld_profile.txt");

    // The hostLinkAction inputs has a different root from the backendAction.
    // Here we confirm that the correct root is on the path
    String hostrootExecPath = hostLinkAction.getPrimaryOutput().getRoot().getExecPathString();
    LtoBackendAction hostBackendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                hostLinkAction,
                "pkg/gen_lib.lto/" + hostrootExecPath + "/pkg/_objs/gen_lib/gen_lib.o");
    assertThat(ActionsTestUtil.baseArtifactNames(hostBackendAction.getInputs()))
        .doesNotContain("cc_profile.txt");
    assertThat(Joiner.on(" ").join(hostBackendAction.getArguments()))
        .doesNotContainMatch("-fbasic-block-sections");

    CppLinkAction hostIndexAction = getIndexAction(hostBackendAction);
    assertThat(hostIndexAction).isNotNull();
    assertThat(ActionsTestUtil.baseArtifactNames(hostIndexAction.getInputs()))
        .doesNotContain("ld_profile.txt");
    assertThat(hostIndexAction.getLinkCommandLineForTesting().getRawLinkArgv().toString())
        .doesNotContainMatch("-Wl,--symbol-ordering-file=.*/ld_profile.txt");

    CppCompileAction hostBitcodeAction =
        (CppCompileAction)
            getPredecessorByInputName(hostIndexAction, "pkg/_objs/gen_lib/gen_lib.indexing.o");
    assertThat(ActionsTestUtil.baseArtifactNames(hostBitcodeAction.getInputs()))
        .doesNotContain("cc_profile.txt");
    assertThat(Joiner.on(" ").join(hostBitcodeAction.getArguments()))
        .doesNotContainMatch("-fbasic-block-sections=");
  }

  private void testPropellerOptimizeOption(boolean label) throws Exception {
    createBuildFiles();

    if (label) {
      scratch.file(
          "fdo/BUILD",
          "propeller_optimize(name='test_propeller_optimize', cc_profile=':cc_profile.txt',"
              + " ld_profile=':ld_profile.txt')");
    } else {
      scratch.file(
          "fdo/BUILD",
          "propeller_optimize(name='test_propeller_optimize',"
              + "absolute_cc_profile='/tmp/cc_profile.txt',"
              + "absolute_ld_profile='/tmp/ld_profile.txt')");
    }
    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.AUTOFDO);

    useConfiguration(
        "--propeller_optimize=//fdo:test_propeller_optimize", "--compilation_mode=opt");

    Artifact binArtifact = getFilesToBuild(getCurrentTarget()).getSingleton();
    String rootExecPath = binArtifact.getRoot().getExecPathString();

    CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact);
    assertThat(linkAction.getOutputs()).containsExactly(binArtifact);

    List<String> commandLine = linkAction.getLinkCommandLineForTesting().getRawLinkArgv();
    assertThat(commandLine.toString())
        .containsMatch("-Wl,--symbol-ordering-file=.*/ld_profile.txt");

    LtoBackendAction backendAction =
        (LtoBackendAction)
            getPredecessorByInputName(
                linkAction, "pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");

    String expectedCompilerFlag = "-fbasic-block-sections=list=.*/cc_profile.txt";
    assertThat(Joiner.on(" ").join(backendAction.getArguments()))
        .containsMatch(expectedCompilerFlag);
    String expectedBuildTypeFlag = "-DBUILD_PROPELLER_TYPE=\"full\"";
    assertThat(Joiner.on(" ").join(backendAction.getArguments()))
        .containsMatch(expectedBuildTypeFlag);
    assertThat(ActionsTestUtil.baseArtifactNames(backendAction.getInputs()))
        .contains("cc_profile.txt");
  }

  @Test
  public void testPropellerOptimizeOptionFromAbsolutePath() throws Exception {
    testPropellerOptimizeOption(false);
  }

  @Test
  public void testPropellerOptimizeOptionFromLabel() throws Exception {
    testPropellerOptimizeOption(true);
  }

  private void testLLVMCachePrefetchBackendOption(String extraOption, boolean asLabel)
      throws Exception {
    createBuildFiles();
    if (asLabel) {
      scratch.file(
          "fdo/BUILD", "fdo_prefetch_hints(name='test_profile', profile=':prefetch.afdo')");
    } else {
      scratch.file(
          "fdo/BUILD",
          "fdo_prefetch_hints(name='test_profile', absolute_path_profile='/tmp/prefetch.afdo')");
    }

    setupThinLTOCrosstool(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.AUTOFDO);
    useConfiguration(
        "--fdo_prefetch_hints=//fdo:test_profile", "--compilation_mode=opt", extraOption);

    String rootExecPath = getRootExecPath();
    LtoBackendAction backendAction =
        getBackendAction("pkg/bin.lto/" + rootExecPath + "/pkg/_objs/bin/binfile.o");

    String expectedCompilerFlag =
        "-prefetch-hints-file="
            + (asLabel ? ".*/prefetch.afdo" : "(blaze|bazel)-out/.*/fdo/.*/prefetch.afdo");
    assertThat(Joiner.on(" ").join(backendAction.getArguments()))
        .containsMatch("-mllvm " + expectedCompilerFlag);

    assertThat(ActionsTestUtil.baseArtifactNames(backendAction.getInputs()))
        .contains("prefetch.afdo");
  }

  @Test
  public void testFdoCachePrefetchLLVMOptionsToBackendFromPath() throws Exception {
    testLLVMCachePrefetchBackendOption("", false);
  }

  @Test
  public void testFdoCachePrefetchAndFdoLLVMOptionsToBackendFromPath() throws Exception {
    testLLVMCachePrefetchBackendOption("--fdo_optimize=/profile.zip", false);
  }

  @Test
  public void testFdoCachePrefetchLLVMOptionsToBackendFromLabel() throws Exception {
    testLLVMCachePrefetchBackendOption("", true);
  }

  @Test
  public void testFdoCachePrefetchAndFdoLLVMOptionsToBackendFromLabel() throws Exception {
    testLLVMCachePrefetchBackendOption("--fdo_optimize=/profile.zip", true);
  }

  @Test
  public void testThinLtoWithoutSupportsStartEndLibError() throws Exception {
    createBuildFiles("testonly = 1,");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures(CppRuleClasses.THIN_LTO));
    checkError("//pkg:bin", "The feature supports_start_end_lib must be enabled.");
  }
}
