// Copyright 2014 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 com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Options.MakeVariableSource;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.config.PerLabelOptions;
import com.google.devtools.build.lib.analysis.skylark.annotations.SkylarkConfigurationField;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.rules.cpp.CppConfigurationLoader.CppConfigurationParameters;
import com.google.devtools.build.lib.rules.cpp.CrosstoolConfigurationLoader.CrosstoolFile;
import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CppConfigurationApi;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * This class represents the C/C++ parts of the {@link BuildConfiguration}, including the host
 * architecture, target architecture, compiler version, and a standard library version. It has
 * information about the tools locations and the flags required for compiling.
 *
 * <p>Before {@link CppConfiguration} is created, two things need to be done:
 *
 * <ol>
 *   <li>choosing a {@link CcToolchainRule} label from {@code toolchains} map attribute of {@link
 *       CcToolchainSuiteRule}.
 *   <li>selection of a {@link
 *       com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain} from the
 *       CROSSTOOL file.
 * </ol>
 *
 * <p>The process goes as follows:
 *
 * <p>Check for existence of {@link CcToolchainSuiteRule}.toolchains[<cpu>|<compiler>], if
 * --compiler is specified, otherwise check for {@link CcToolchainSuiteRule}.toolchains[<cpu>].
 *
 * <ul>
 *   <li>if a value is found, load the {@link CcToolchainRule} rule and look for the {@code
 *       toolchain_identifier} attribute.
 *   <li>
 *       <ul>
 *         <li>if the attribute exists, loop through all the {@code CToolchain}s in CROSSTOOL and
 *             select the one with the matching toolchain identifier.
 *         <li>otherwise fall back to selecting the CToolchain from CROSSTOOL by matching the --cpu
 *             and --compiler values.
 *       </ul>
 *   <li>If a value is not found, select the CToolchain from CROSSTOOL by matching the --cpu and
 *       --compiler values, and construct the key as follows: <toolchain.cpu>|<toolchain.compiler>.
 * </ul>
 */
@Immutable
public final class CppConfiguration extends BuildConfiguration.Fragment
    implements CppConfigurationApi<InvalidConfigurationException> {
  /**
   * String indicating a Mac system, for example when used in a crosstool configuration's host or
   * target system name.
   */
  public static final String MAC_SYSTEM_NAME = "x86_64-apple-macosx";

  /** String constant for CC_FLAGS make variable name */
  public static final String CC_FLAGS_MAKE_VARIABLE_NAME = "CC_FLAGS";

  /**
   * An enumeration of all the tools that comprise a toolchain.
   */
  public enum Tool {
    AR("ar"),
    CPP("cpp"),
    GCC("gcc"),
    GCOV("gcov"),
    GCOVTOOL("gcov-tool"),
    LD("ld"),
    NM("nm"),
    OBJCOPY("objcopy"),
    OBJDUMP("objdump"),
    STRIP("strip"),
    DWP("dwp"),
    LLVM_PROFDATA("llvm-profdata");

    private final String namePart;

    private Tool(String namePart) {
      this.namePart = namePart;
    }

    public String getNamePart() {
      return namePart;
    }
  }

  /**
   * Values for the --hdrs_check option. Note that Bazel only supports and will default to "strict".
   */
  public enum HeadersCheckingMode {
    /**
     * Legacy behavior: Silently allow any source header file in any of the directories of the
     * containing package to be included by sources in this rule and dependent rules.
     */
    LOOSE,
    /** Disallow undeclared headers. */
    STRICT;

    public static HeadersCheckingMode getValue(String value) {
      if (value.equalsIgnoreCase("loose") || value.equalsIgnoreCase("warn")) {
        return LOOSE;
      }
      if (value.equalsIgnoreCase("strict")) {
        return STRICT;
      }
      throw new IllegalArgumentException();
    }
  }

  /**
   * --dynamic_mode parses to DynamicModeFlag, but AUTO will be translated based on platform,
   * resulting in a DynamicMode value.
   */
  public enum DynamicMode     { OFF, DEFAULT, FULLY }

  /**
   * This enumeration is used for the --strip option.
   */
  public enum StripMode {

    ALWAYS("always"),       // Always strip.
    SOMETIMES("sometimes"), // Strip iff compilationMode == FASTBUILD.
    NEVER("never");         // Never strip.

    private final String mode;

    private StripMode(String mode) {
      this.mode = mode;
    }

    @Override
    public String toString() {
      return mode;
    }
  }

  /**
   * This macro will be passed as a command-line parameter (eg. -DBUILD_FDO_TYPE="AUTOFDO"). For
   * possible values see {@code CppModel.getFdoBuildStamp()}.
   */
  public static final String FDO_STAMP_MACRO = "BUILD_FDO_TYPE";

  private final Label crosstoolTop;
  private final CrosstoolFile crosstoolFile;
  // TODO(lberki): desiredCpu *should* be always the same as targetCpu, except that we don't check
  // that the CPU we get from the toolchain matches BuildConfiguration.Options.cpu . So we store
  // it here so that the output directory doesn't depend on the CToolchain. When we will eventually
  // verify that the two are the same, we can remove one of desiredCpu and targetCpu.
  private final String desiredCpu;
  private final PathFragment crosstoolTopPathFragment;

  private final PathFragment fdoPath;
  private final Label fdoOptimizeLabel;

  // TODO(bazel-team): All these labels (except for ccCompilerRuleLabel) can be removed once the
  // transition to the cc_compiler rule is complete.
  private final Label ccToolchainLabel;
  private final Label stlLabel;

  // TODO(kmensah): This is temporary until all the Skylark functions that need this can be removed.
  private final PathFragment nonConfiguredSysroot;
  private final Label sysrootLabel;

  private final ImmutableList<String> compilerFlags;
  private final ImmutableList<String> cxxFlags;
  private final ImmutableList<String> unfilteredCompilerFlags;
  private final ImmutableList<String> conlyopts;

  private final ImmutableList<String> mostlyStaticLinkFlags;
  private final ImmutableList<String> mostlyStaticSharedLinkFlags;
  private final ImmutableList<String> dynamicLinkFlags;
  private final ImmutableList<String> copts;
  private final ImmutableList<String> cxxopts;

  private final ImmutableList<String> linkopts;
  private final ImmutableList<String> ltoindexOptions;
  private final ImmutableList<String> ltobackendOptions;

  private final CppOptions cppOptions;
  private final CpuTransformer cpuTransformerEnum;

  // The dynamic mode for linking.
  private final boolean stripBinaries;
  private final CompilationMode compilationMode;

  private final boolean shouldProvideMakeVariables;

  private final CppToolchainInfo cppToolchainInfo;

  static CppConfiguration create(CppConfigurationParameters params)
      throws InvalidConfigurationException {
    CppOptions cppOptions = params.cppOptions;
    PathFragment crosstoolTopPathFragment =
        params.crosstoolTop.getPackageIdentifier().getPathUnderExecRoot();
    CppToolchainInfo cppToolchainInfo =
        CppToolchainInfo.create(
            crosstoolTopPathFragment,
            params.ccToolchainLabel,
            params.ccToolchainConfigInfo,
            cppOptions.disableLegacyCrosstoolFields,
            cppOptions.disableCompilationModeFlags,
            cppOptions.disableLinkingModeFlags);

    CompilationMode compilationMode = params.commonOptions.compilationMode;

    ImmutableList.Builder<String> coptsBuilder =
        ImmutableList.<String>builder()
            .addAll(cppToolchainInfo.getCompilerFlags())
            .addAll(cppToolchainInfo.getCFlagsByCompilationMode().get(compilationMode));
    if (cppOptions.experimentalOmitfp) {
      coptsBuilder.add("-fomit-frame-pointer");
      coptsBuilder.add("-fasynchronous-unwind-tables");
      coptsBuilder.add("-DNO_FRAME_POINTER");
    }
    coptsBuilder.addAll(cppOptions.coptList);

    ImmutableList<String> cxxOpts =
        ImmutableList.<String>builder()
            .addAll(cppToolchainInfo.getCxxFlags())
            .addAll(cppToolchainInfo.getCxxFlagsByCompilationMode().get(compilationMode))
            .addAll(cppOptions.cxxoptList)
            .build();

    ImmutableList.Builder<String> linkoptsBuilder = ImmutableList.builder();
    linkoptsBuilder.addAll(cppOptions.linkoptList);
    if (cppOptions.experimentalOmitfp) {
      linkoptsBuilder.add("-Wl,--eh-frame-hdr");
    }

    return new CppConfiguration(
        params.crosstoolTop,
        params.crosstoolFile,
        Preconditions.checkNotNull(params.commonOptions.cpu),
        crosstoolTopPathFragment,
        params.fdoPath,
        params.fdoOptimizeLabel,
        params.ccToolchainLabel,
        params.stlLabel,
        params.sysrootLabel == null
            ? cppToolchainInfo.getDefaultSysroot()
            : params.sysrootLabel.getPackageFragment(),
        params.sysrootLabel,
        coptsBuilder.build(),
        cxxOpts,
        cppToolchainInfo.getUnfilteredCompilerOptions(/* sysroot= */ null),
        ImmutableList.copyOf(cppOptions.conlyoptList),
        cppToolchainInfo.configureAllLegacyLinkOptions(compilationMode, LinkingMode.STATIC),
        cppToolchainInfo.configureAllLegacyLinkOptions(
            compilationMode, LinkingMode.LEGACY_MOSTLY_STATIC_LIBRARIES),
        cppToolchainInfo.configureAllLegacyLinkOptions(compilationMode, LinkingMode.DYNAMIC),
        ImmutableList.copyOf(cppOptions.coptList),
        ImmutableList.copyOf(cppOptions.cxxoptList),
        linkoptsBuilder.build(),
        ImmutableList.copyOf(cppOptions.ltoindexoptList),
        ImmutableList.copyOf(cppOptions.ltobackendoptList),
        cppOptions,
        params.cpuTransformer,
        (cppOptions.stripBinaries == StripMode.ALWAYS
            || (cppOptions.stripBinaries == StripMode.SOMETIMES
                && compilationMode == CompilationMode.FASTBUILD)),
        compilationMode,
        params.commonOptions.makeVariableSource == MakeVariableSource.CONFIGURATION,
        cppToolchainInfo);
  }

  private CppConfiguration(
      Label crosstoolTop,
      CrosstoolFile crosstoolFile,
      String desiredCpu,
      PathFragment crosstoolTopPathFragment,
      PathFragment fdoPath,
      Label fdoOptimizeLabel,
      Label ccToolchainLabel,
      Label stlLabel,
      PathFragment nonConfiguredSysroot,
      Label sysrootLabel,
      ImmutableList<String> compilerFlags,
      ImmutableList<String> cxxFlags,
      ImmutableList<String> unfilteredCompilerFlags,
      ImmutableList<String> conlyopts,
      ImmutableList<String> mostlyStaticLinkFlags,
      ImmutableList<String> mostlyStaticSharedLinkFlags,
      ImmutableList<String> dynamicLinkFlags,
      ImmutableList<String> copts,
      ImmutableList<String> cxxopts,
      ImmutableList<String> linkopts,
      ImmutableList<String> ltoindexOptions,
      ImmutableList<String> ltobackendOptions,
      CppOptions cppOptions,
      CpuTransformer cpuTransformerEnum,
      boolean stripBinaries,
      CompilationMode compilationMode,
      boolean shouldProvideMakeVariables,
      CppToolchainInfo cppToolchainInfo) {
    this.crosstoolTop = crosstoolTop;
    this.crosstoolFile = crosstoolFile;
    this.desiredCpu = desiredCpu;
    this.crosstoolTopPathFragment = crosstoolTopPathFragment;
    this.fdoPath = fdoPath;
    this.fdoOptimizeLabel = fdoOptimizeLabel;
    this.ccToolchainLabel = ccToolchainLabel;
    this.stlLabel = stlLabel;
    this.nonConfiguredSysroot = nonConfiguredSysroot;
    this.sysrootLabel = sysrootLabel;
    this.compilerFlags = compilerFlags;
    this.cxxFlags = cxxFlags;
    this.unfilteredCompilerFlags = unfilteredCompilerFlags;
    this.conlyopts = conlyopts;
    this.mostlyStaticLinkFlags = mostlyStaticLinkFlags;
    this.mostlyStaticSharedLinkFlags = mostlyStaticSharedLinkFlags;
    this.dynamicLinkFlags = dynamicLinkFlags;
    this.copts = copts;
    this.cxxopts = cxxopts;
    this.linkopts = linkopts;
    this.ltoindexOptions = ltoindexOptions;
    this.ltobackendOptions = ltobackendOptions;
    this.cppOptions = cppOptions;
    this.cpuTransformerEnum = cpuTransformerEnum;
    this.stripBinaries = stripBinaries;
    this.compilationMode = compilationMode;
    this.shouldProvideMakeVariables = shouldProvideMakeVariables;
    this.cppToolchainInfo = cppToolchainInfo;
  }

  @VisibleForTesting
  static LinkingMode importLinkingMode(CrosstoolConfig.LinkingMode mode) {
    switch (mode.name()) {
      case "FULLY_STATIC":
        return LinkingMode.LEGACY_FULLY_STATIC;
      case "MOSTLY_STATIC_LIBRARIES":
        return LinkingMode.LEGACY_MOSTLY_STATIC_LIBRARIES;
      case "MOSTLY_STATIC":
        return LinkingMode.STATIC;
      case "DYNAMIC":
        return LinkingMode.DYNAMIC;
      default:
        throw new IllegalArgumentException(
            String.format("Linking mode '%s' not known.", mode.name()));
    }
  }

  /** Returns the {@link CppToolchainInfo} used by this configuration. */
  public CppToolchainInfo getCppToolchainInfo() {
    return cppToolchainInfo;
  }

  /**
   * Returns the toolchain identifier, which uniquely identifies the compiler version, target libc
   * version, and target cpu.
   */
  public String getToolchainIdentifier() {
    return cppToolchainInfo.getToolchainIdentifier();
  }

  /** Returns the contents of the CROSSTOOL for this configuration. */
  public CrosstoolFile getCrosstoolFile() {
    return crosstoolFile;
  }

  /** Returns the label of the CROSSTOOL for this configuration. */
  public Label getCrosstoolTop() {
    return crosstoolTop;
  }

  /** Returns the transformer that should be applied to cpu names in toolchain selection. */
  public Function<String, String> getCpuTransformer() {
    return cpuTransformerEnum.getTransformer();
  }

  /**
   * Returns the path of the crosstool.
   */
  public PathFragment getCrosstoolTopPathFragment() {
    return cppToolchainInfo.getCrosstoolTopPathFragment();
  }

  @Override
  public String toString() {
    return cppToolchainInfo.toString();
  }

  /**
   * Returns the compiler version string (e.g. "gcc-4.1.1").
   *
   * <p>Deprecated: Use {@link CcToolchainProvider#getCompiler()}
   */
  // TODO(b/68038647): Remove once make variables are no longer derived from CppConfiguration.
  @Override
  @Deprecated
  public String getCompiler() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    return cppToolchainInfo.getCompiler();
  }

  /**
   * Returns the libc version string (e.g. "glibc-2.2.2").
   *
   * <p>Deprecated: Use {@link CcToolchainProvider#getTargetLibc()}
   */
  // TODO(b/68038647): Remove once make variables are no longer derived from CppConfiguration.
  @Override
  @Deprecated
  public String getTargetLibc() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    return cppToolchainInfo.getTargetLibc();
  }

  /**
   * Returns the target architecture using blaze-specific constants (e.g. "piii").
   *
   * <p>Deprecated: Use {@link CcToolchainProvider#getTargetCpu()}
   */
  // TODO(b/68038647): Remove once skylark callers are migrated.
  @Override
  @Deprecated
  public String getTargetCpu() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    return cppToolchainInfo.getTargetCpu();
  }

  /**
   * Returns the path fragment that is either absolute or relative to the execution root that can be
   * used to execute the given tool.
   *
   * <p>Deprecated: Use {@link CcToolchainProvider#getToolPathFragment(Tool)}
   */
  @Deprecated
  public PathFragment getToolPathFragment(CppConfiguration.Tool tool) {
    return cppToolchainInfo.getToolPathFragment(tool);
  }

  /**
   * Returns the label of the <code>cc_compiler</code> rule for the C++ configuration.
   */
  @SkylarkConfigurationField(
      name = "cc_toolchain",
      doc = "The label of the target describing the C++ toolchain",
      defaultLabel = "//tools/cpp:crosstool",
      defaultInToolRepository = true
  )
  public Label getCcToolchainRuleLabel() {
    return ccToolchainLabel;
  }

  /**
   * Returns the configured features of the toolchain. Rules should not call this directly, but
   * instead use {@code CcToolchainProvider.getFeatures}.
   */
  public CcToolchainFeatures getFeatures() {
    return cppToolchainInfo.getFeatures();
  }

  /**
   * Returns the configured current compilation mode. Rules should not call this directly, but
   * instead use {@code CcToolchainProvider.getCompilationMode}.
   */
  public CompilationMode getCompilationMode() {
    return compilationMode;
  }

  @Override
  @Deprecated
  public ImmutableList<String> getBuiltInIncludeDirectoriesForSkylark()
      throws InvalidConfigurationException, EvalException {
    checkForToolchainSkylarkApiAvailability();
    return getBuiltInIncludeDirectories(nonConfiguredSysroot)
            .stream()
            .map(PathFragment::getPathString)
            .collect(ImmutableList.toImmutableList());
  }

  /**
   * Returns the built-in list of system include paths for the toolchain compiler. All paths in this
   * list should be relative to the exec directory. They may be absolute if they are also installed
   * on the remote build nodes or for local compilation.
   *
   * <p>TODO(b/64384912): Migrate skylark callers to
   * CcToolchainProvider#getBuiltinIncludeDirectories and delete this method.
   */
  private ImmutableList<PathFragment> getBuiltInIncludeDirectories(PathFragment sysroot)
      throws InvalidConfigurationException {
    ImmutableList.Builder<PathFragment> builtInIncludeDirectoriesBuilder = ImmutableList.builder();
    for (String s : cppToolchainInfo.getRawBuiltInIncludeDirectories()) {
      builtInIncludeDirectoriesBuilder.add(
          CcToolchain.resolveIncludeDir(s, sysroot, crosstoolTopPathFragment));
    }
    return builtInIncludeDirectoriesBuilder.build();
  }

  /**
   * Returns the sysroot to be used. If the toolchain compiler does not support
   * different sysroots, or the sysroot is the same as the default sysroot, then
   * this method returns <code>null</code>.
   */
  @Override
  @Deprecated
  public String getSysroot() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    return nonConfiguredSysroot.getPathString();
  }

  public Label getSysrootLabel() {
    return sysrootLabel;
  }

  /**
   * Returns the default options to use for compiling C, C++, and assembler. This is just the
   * options that should be used for all three languages. There may be additional C-specific or
   * C++-specific options that should be used, in addition to the ones returned by this method.
   *
   * <p>Deprecated: Use {@link CcToolchainProvider#getLegacyCompileOptionsWithCopts()}
   */
  // TODO(b/64384912): Migrate skylark callers and remove.
  @Override
  @Deprecated
  public ImmutableList<String> getCompilerOptions(Iterable<String> featuresNotUsedAnymore)
    throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    checkForLegacyCompilationApiAvailability();
    return compilerFlags;
  }

  /**
   * Returns the list of additional C-specific options to use for compiling C. These should be go on
   * the command line after the common options returned by {@link #getCompilerOptions}.
   */
  // TODO(b/64384912): Migrate skylark callers and remove.
  @Override
  @Deprecated
  public ImmutableList<String> getCOptionsForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    checkForLegacyCompilationApiAvailability();
    return getCOptions();
  }

  public ImmutableList<String> getCOptions() {
    return conlyopts;
  }

  /**
   * Returns the list of additional C++-specific options to use for compiling C++. These should be
   * on the command line after the common options returned by {@link #getCompilerOptions}.
   *
   * <p>Deprecated: Use {@link CcToolchainProvider#getCxxOptionsWithCopts}
   */
  // TODO(b/64384912): Migrate skylark callers and remove.
  @Override
  @Deprecated
  public ImmutableList<String> getCxxOptions(Iterable<String> featuresNotUsedAnymore)
    throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    checkForLegacyCompilationApiAvailability();
    return cxxFlags;
  }

  /**
   * Returns the default list of options which cannot be filtered by BUILD rules. These should be
   * appended to the command line after filtering.
   *
   * @deprecated since it uses nonconfigured sysroot. Use {@link
   *     CcToolchainProvider#getUnfilteredCompilerOptionsWithSysroot(Iterable)} if you *really* need
   *     to.
   */
  // TODO(b/65401585): Migrate existing uses to cc_toolchain and cleanup here.
  @Deprecated
  @Override
  public ImmutableList<String> getUnfilteredCompilerOptionsWithLegacySysroot(
      Iterable<String> featuresNotUsedAnymore) throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    checkForLegacyCompilationApiAvailability();
    return getUnfilteredCompilerOptionsDoNotUse(nonConfiguredSysroot);
  }

  /**
   * @deprecated since it hardcodes --sysroot flag. Use {@link
   *     com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration} instead.
   */
  // TODO(b/65401585): Migrate existing uses to cc_toolchain and cleanup here.
  @Deprecated
  ImmutableList<String> getUnfilteredCompilerOptionsDoNotUse(@Nullable PathFragment sysroot)
    throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    if (sysroot == null) {
      return unfilteredCompilerFlags;
    }
    return ImmutableList.<String>builder()
        .add("--sysroot=" + sysroot)
        .addAll(unfilteredCompilerFlags)
        .build();
  }

  /**
   * Returns the set of command-line linker options, including any flags inferred from the
   * command-line options.
   *
   * @see Link
   * @deprecated since it uses nonconfigured sysroot. Use
   * {@link CcToolchainProvider#getLinkOptionsWithSysroot()} if you *really* need to.
   */
  // TODO(b/65401585): Migrate existing uses to cc_toolchain and cleanup here.
  @Deprecated
  @Override
  public ImmutableList<String> getLinkOptionsWithLegacySysroot() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    checkForLegacyLinkingApiAvailability();
    return getLinkOptionsDoNotUse(nonConfiguredSysroot);
  }

  /**
   * @deprecated since it hardcodes --sysroot flag. Use
   * {@link com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration}
   * instead.
   */
  // TODO(b/65401585): Migrate existing uses to cc_toolchain and cleanup here.
  @Deprecated
  ImmutableList<String> getLinkOptionsDoNotUse(@Nullable PathFragment sysroot) {
    if (sysroot == null) {
      return linkopts;
    } else {
      return ImmutableList.<String>builder().addAll(linkopts).add("--sysroot=" + sysroot).build();
    }
  }

  public boolean hasSharedLinkOption() {
    return linkopts.contains("-shared");
  }

  /** Returns the set of command-line LTO indexing options. */
  public ImmutableList<String> getLtoIndexOptions() {
    return ltoindexOptions;
  }

  /** Returns the set of command-line LTO backend options. */
  public ImmutableList<String> getLtoBackendOptions() {
    return ltobackendOptions;
  }

  /**
   * Returns the immutable list of linker options for fully statically linked outputs. Does not
   * include command-line options passed via --linkopt or --linkopts.
   *
   * @param featuresNotUsedAnymore
   * @param sharedLib true if the output is a shared lib, false if it's an executable
   *     <p>Deprecated: Use {@link CppHelper#getFullyStaticLinkOptions(CppConfiguration,
   *     CcToolchainProvider, boolean)}
   */
  // TODO(b/64384912): Migrate skylark users to cc_common and remove.
  @Override
  @Deprecated
  public ImmutableList<String> getFullyStaticLinkOptions(
      Iterable<String> featuresNotUsedAnymore, Boolean sharedLib) throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    checkForLegacyLinkingApiAvailability();
    if (!sharedLib) {
      throw new EvalException(
          Location.BUILTIN, "fully_static_link_options is deprecated, new uses are not allowed.");
    }
    return getSharedLibraryLinkOptions(mostlyStaticLinkFlags);
  }

  /**
   * Returns the immutable list of linker options for mostly statically linked outputs. Does not
   * include command-line options passed via --linkopt or --linkopts.
   *
   * @param featuresNotUsedAnymore
   * @param sharedLib true if the output is a shared lib, false if it's an executable
   *     <p>Deprecated: Use {@link CppHelper#getMostlyStaticLinkOptions( CppConfiguration,
   *     CcToolchainProvider, boolean, boolean)}
   */
  // TODO(b/64384912): Migrate skylark users to cc_common and remove.
  @Override
  @Deprecated
  public ImmutableList<String> getMostlyStaticLinkOptions(
      Iterable<String> featuresNotUsedAnymore, Boolean sharedLib) throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    checkForLegacyLinkingApiAvailability();
    if (sharedLib) {
      return getSharedLibraryLinkOptions(
          cppToolchainInfo.supportsEmbeddedRuntimes()
              ? mostlyStaticSharedLinkFlags
              : dynamicLinkFlags);
    } else {
      return mostlyStaticLinkFlags;
    }
  }

  /**
   * Returns the immutable list of linker options for artifacts that are not fully or mostly
   * statically linked. Does not include command-line options passed via --linkopt or --linkopts.
   *
   * @param featuresNotUsedAnymore
   * @param sharedLib true if the output is a shared lib, false if it's an executable
   *     <p>Deprecated: Use {@link CppHelper#getDynamicLinkOptions(CppConfiguration,
   *     CcToolchainProvider, Boolean)}
   */
  // TODO(b/64384912): Migrate skylark users to cc_common and remove.
  @Override
  @Deprecated
  public ImmutableList<String> getDynamicLinkOptions(
      Iterable<String> featuresNotUsedAnymore, Boolean sharedLib) throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    checkForLegacyLinkingApiAvailability();
    if (sharedLib) {
      return getSharedLibraryLinkOptions(dynamicLinkFlags);
    } else {
      return dynamicLinkFlags;
    }
  }

  /**
   * Returns link options for the specified flag list, combined with universal options for all
   * shared libraries (regardless of link staticness).
   *
   * <p>Deprecated: Use {@link CcToolchainProvider#getSharedLibraryLinkOptions}
   */
  // TODO(b/64384912): Migrate skylark dependants and delete.
  private ImmutableList<String> getSharedLibraryLinkOptions(ImmutableList<String> flags) {
    return cppToolchainInfo.getSharedLibraryLinkOptions(flags);
  }

  /**
   * Returns a map of additional make variables for use by {@link
   * BuildConfiguration}. These are to used to allow some build rules to
   * avoid the limits on stack frame sizes and variable-length arrays.
   *
   * <p>The returned map must contain an entry for {@code STACK_FRAME_UNLIMITED},
   * though the entry may be an empty string.
   */
  public ImmutableMap<String, String> getAdditionalMakeVariables() {
    return cppToolchainInfo.getAdditionalMakeVariables();
  }

  /**
   * Returns the execution path to the linker binary to use for this build. Relative paths are
   * relative to the execution root.
   */
  @Override
  @Deprecated
  public String getLdExecutableForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    PathFragment ldExecutable = getToolPathFragment(CppConfiguration.Tool.LD);
    return ldExecutable != null ? ldExecutable.getPathString() : "";
  }

  @SkylarkCallable(
      name = "minimum_os_version",
      doc = "The minimum OS version for C/C++ compilation.")
  public String getMinimumOsVersion() {
    return cppOptions.minimumOsVersion;
  }

  /** Returns the value of the --dynamic_mode flag. */
  public DynamicMode getDynamicModeFlag() {
    return cppOptions.dynamicMode;
  }

  public boolean getLinkCompileOutputSeparately() {
    return cppOptions.linkCompileOutputSeparately;
  }

  /**
   * Returns the STL label if given on the command line. {@code null}
   * otherwise.
   */
  public Label getStl() {
    return stlLabel;
  }

  @SkylarkConfigurationField(
      name = "stl",
      doc = "The label of the STL target",
      defaultLabel = "//third_party/stl",
      defaultInToolRepository = false
  )
  public Label getSkylarkStl() {
    if (stlLabel == null) {
      try {
        return Label.parseAbsolute("//third_party/stl", ImmutableMap.of());
      } catch (LabelSyntaxException e) {
        throw new IllegalStateException("STL label not formatted correctly", e);
      }
    }
    return stlLabel;
  }

  public boolean isFdo() {
    return cppOptions.isFdo();
  }

  /**
   * Returns whether or not to strip the binaries.
   */
  public boolean shouldStripBinaries() {
    return stripBinaries;
  }

  /**
   * Returns the additional options to pass to strip when generating a
   * {@code <name>.stripped} binary by this build.
   */
  public ImmutableList<String> getStripOpts() {
    return ImmutableList.copyOf(cppOptions.stripoptList);
  }

  /**
   * Returns whether temporary outputs from gcc will be saved.
   */
  public boolean getSaveTemps() {
    return cppOptions.saveTemps;
  }

  /**
   * Returns the {@link PerLabelOptions} to apply to the gcc command line, if
   * the label of the compiled file matches the regular expression.
   */
  public ImmutableList<PerLabelOptions> getPerFileCopts() {
    return ImmutableList.copyOf(cppOptions.perFileCopts);
  }

  /**
   * Returns the {@link PerLabelOptions} to apply to the LTO Backend command line, if the compiled
   * object matches the regular expression.
   */
  public ImmutableList<PerLabelOptions> getPerFileLtoBackendOpts() {
    return ImmutableList.copyOf(cppOptions.perFileLtoBackendOpts);
  }

  /**
   * Returns the custom malloc library label.
   */
  public Label customMalloc() {
    return cppOptions.customMalloc;
  }

  /**
   * Returns whether we are processing headers in dependencies of built C++ targets.
   */
  public boolean processHeadersInDependencies() {
    return cppOptions.processHeadersInDependencies;
  }

  /** Returns true if --fission contains the current compilation mode. */
  public boolean fissionIsActiveForCurrentCompilationMode() {
    return cppOptions.fissionModes.contains(compilationMode);
  }

  /** Returns true if --build_test_dwp is set on this build. */
  public boolean buildTestDwpIsActivated() {
    return cppOptions.buildTestDwp;
  }

  /**
   * Returns true if all C++ compilations should produce position-independent code, links should
   * produce position-independent executables, and dependencies with equivalent pre-built pic and
   * nopic versions should apply the pic versions. Returns false if default settings should be
   * applied (i.e. make no special provisions for pic code).
   */
  public boolean forcePic() {
    return cppOptions.forcePic;
  }

  /** Returns true if --start_end_lib is set on this build. */
  public boolean startEndLibIsRequested() {
    return cppOptions.useStartEndLib;
  }

  public boolean legacyWholeArchive() {
    return cppOptions.legacyWholeArchive;
  }

  public boolean getSymbolCounts() {
    return cppOptions.symbolCounts;
  }

  public boolean getInmemoryDotdFiles() {
    return cppOptions.inmemoryDotdFiles;
  }

  public boolean getPruneCppModules() {
    return cppOptions.pruneCppModules;
  }

  public boolean getPruneCppInputDiscovery() {
    return cppOptions.pruneCppInputDiscovery;
  }

  public boolean getNoDotdScanningWithModules() {
    return cppOptions.noDotdScanningWithModules;
  }

  public boolean getParseHeadersVerifiesModules() {
    return cppOptions.parseHeadersVerifiesModules;
  }

  public boolean getUseInterfaceSharedObjects() {
    return cppOptions.useInterfaceSharedObjects;
  }

  /**
   * Returns the path to the GNU binutils 'objcopy' binary to use for this build. (Corresponds to
   * $(OBJCOPY) in make-dbg.) Relative paths are relative to the execution root.
   */
  @Override
  @Deprecated
  public String getObjCopyExecutableForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    PathFragment objCopyExecutable = getToolPathFragment(Tool.OBJCOPY);
    return objCopyExecutable != null ? objCopyExecutable.getPathString() : "";
  }

  @Override
  @Deprecated
  public String getCppExecutableForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    PathFragment cppExecutable = getToolPathFragment(Tool.GCC);
    return cppExecutable != null ? cppExecutable.getPathString() : "";
  }

  @Override
  @Deprecated
  public String getCpreprocessorExecutableForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    PathFragment cpreprocessorExecutable = getToolPathFragment(Tool.CPP);
    return cpreprocessorExecutable != null ? cpreprocessorExecutable.getPathString() : "";
  }

  @Override
  @Deprecated
  public String getNmExecutableForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    PathFragment nmExecutable = getToolPathFragment(Tool.NM);
    return nmExecutable != null ? nmExecutable.getPathString() : "";
  }

  @Override
  @Deprecated
  public String getObjdumpExecutableForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    PathFragment objdumpExecutable = getToolPathFragment(Tool.OBJDUMP);
    return objdumpExecutable != null ? objdumpExecutable.getPathString() : "";
  }

  @Override
  @Deprecated
  public String getArExecutableForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    PathFragment arExecutable = getToolPathFragment(Tool.AR);
    return arExecutable != null ? arExecutable.getPathString() : "";
  }

  @Override
  @Deprecated
  public String getStripExecutableForSkylark() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    PathFragment stripExecutable = getToolPathFragment(Tool.STRIP);
    return stripExecutable != null ? stripExecutable.getPathString() : "";
  }

  /**
   * Returns the GNU System Name
   *
   */
  //TODO(b/70225490): Migrate skylark dependants to CcToolchainProvider and delete.
  @Override
  @Deprecated
  public String getTargetGnuSystemName() throws EvalException {
    checkForToolchainSkylarkApiAvailability();
    return cppToolchainInfo.getTargetGnuSystemName();
  }

  /** Returns whether this configuration will use libunwind for stack unwinding. */
  public boolean isOmitfp() {
    return cppOptions.experimentalOmitfp;
  }

  /** Returns flags passed to Bazel by --copt option. */
  @Override
  public ImmutableList<String> getCopts() {
    return copts;
  }

  /** Returns flags passed to Bazel by --cxxopt option. */
  @Override
  public ImmutableList<String> getCxxopts() {
    return cxxopts;
  }

  /** Returns flags passed to Bazel by --conlyopt option. */
  @Override
  public ImmutableList<String> getConlyopts() {
    return conlyopts;
  }

  /** Returns flags passed to Bazel by --linkopt option. */
  @Override
  public ImmutableList<String> getLinkopts() {
    return linkopts;
  }

  @Override
  public void reportInvalidOptions(EventHandler reporter, BuildOptions buildOptions) {
    CppOptions cppOptions = buildOptions.get(CppOptions.class);
    if (stripBinaries) {
      boolean warn = cppOptions.coptList.contains("-g");
      for (PerLabelOptions opt : cppOptions.perFileCopts) {
        warn |= opt.getOptions().contains("-g");
      }
      if (warn) {
        reporter.handle(
            Event.warn(
                "Stripping enabled, but '--copt=-g' (or --per_file_copt=...@-g) specified. "
                    + "Debug information will be generated and then stripped away. This is "
                    + "probably not what you want! Use '-c dbg' for debug mode, or use "
                    + "'--strip=never' to disable stripping"));
      }
    }

    // FDO
    if (cppOptions.getFdoOptimize() != null && cppOptions.fdoProfileLabel != null) {
      reporter.handle(Event.error("Both --fdo_optimize and --fdo_profile specified"));
    }

    if (cppOptions.fdoInstrumentForBuild != null) {
      if (cppOptions.getFdoOptimize() != null || cppOptions.fdoProfileLabel != null) {
        reporter.handle(
            Event.error(
                "Cannot instrument and optimize for FDO at the same time. Remove one of the "
                    + "'--fdo_instrument' and '--fdo_optimize/--fdo_profile' options"));
      }
      if (!cppOptions.coptList.contains("-Wno-error")) {
        // This is effectively impossible. --fdo_instrument adds this value, and only invocation
        // policy could remove it.
        reporter.handle(Event.error("Cannot instrument FDO without --copt including -Wno-error."));
      }
    }

    // This is an assertion check vs. user error because users can't trigger this state.
    Verify.verify(
        !(buildOptions.get(BuildConfiguration.Options.class).isHost && cppOptions.isFdo()),
        "FDO state should not propagate to the host configuration");
  }

  @Override
  public void addGlobalMakeVariables(ImmutableMap.Builder<String, String> globalMakeEnvBuilder) {
    if (cppOptions.disableMakeVariables || !cppOptions.enableMakeVariables) {
      return;
    }

    if (!shouldProvideMakeVariables) {
      return;
    }
    globalMakeEnvBuilder.putAll(
        CcToolchainProvider.getCppBuildVariables(
            this::getToolPathFragment,
            cppToolchainInfo.getTargetLibc(),
            cppToolchainInfo.getCompiler(),
            desiredCpu,
            crosstoolTopPathFragment,
            cppToolchainInfo.getAbiGlibcVersion(),
            cppToolchainInfo.getAbi(),
            getAdditionalMakeVariables()));
  }

  @Override
  public String getOutputDirectoryName() {
    String toolchainPrefix = desiredCpu;
    if (!cppOptions.outputDirectoryTag.isEmpty()) {
      toolchainPrefix += "-" + cppOptions.outputDirectoryTag;
    }

    return toolchainPrefix;
  }

  /**
   * Returns true if we should share identical native libraries between different targets.
   */
  public boolean shareNativeDeps() {
    return cppOptions.shareNativeDeps;
  }

  public boolean isStrictSystemIncludes() {
    return cppOptions.strictSystemIncludes;
  }

  @Override
  public Map<String, Object> lateBoundOptionDefaults() {
    // --compiler initially defaults to null because its *actual* default isn't known
    // until it's read from the CROSSTOOL. Feed the CROSSTOOL defaults in here.
    return ImmutableMap.of("compiler", cppToolchainInfo.getCompiler());
  }

  public String getFdoInstrument() {
    return cppOptions.fdoInstrumentForBuild;
  }

  public PathFragment getFdoPath() {
    return fdoPath;
  }

  public Label getFdoOptimizeLabel() {
    return fdoOptimizeLabel;
  }

  public Label getFdoPrefetchHintsLabel() {
    return cppOptions.getFdoPrefetchHintsLabel();
  }

  public Label getFdoProfileLabel() {
    return cppOptions.fdoProfileLabel;
  }

  public boolean isFdoAbsolutePathEnabled() {
    return cppOptions.enableFdoProfileAbsolutePath;
  }

  public boolean useLLVMCoverageMapFormat() {
    return cppOptions.useLLVMCoverageMapFormat;
  }

  public boolean disableLegacyCrosstoolFields() {
    return cppOptions.disableLegacyCrosstoolFields;
  }

  public boolean disableCompilationModeFlags() {
    return cppOptions.disableCompilationModeFlags;
  }

  public boolean disableLinkingModeFlags() {
    return cppOptions.disableLinkingModeFlags;
  }

  public boolean disableMakeVariables() {
    return cppOptions.disableMakeVariables || !cppOptions.enableMakeVariables;
  }

  public boolean enableLinkoptsInUserLinkFlags() {
    return cppOptions.enableLinkoptsInUserLinkFlags;
  }

  public boolean disableEmittingStaticLibgcc() {
    return cppOptions.disableEmittingStaticLibgcc;
  }

  public boolean disableDepsetInUserFlags() {
    return cppOptions.disableDepsetInUserFlags;
  }

  private void checkForToolchainSkylarkApiAvailability() throws EvalException {
    if (cppOptions.disableLegacyToolchainSkylarkApi
        || !cppOptions.enableLegacyToolchainSkylarkApi) {
      throw new EvalException(null, "Information about the C++ toolchain API is not accessible "
          + "anymore through ctx.fragments.cpp . Use CcToolchainInfo instead.");
    }
  }

  public void checkForLegacyCompilationApiAvailability() throws EvalException {
    if (cppOptions.disableLegacyCompilationApi) {
      throw new EvalException(
          null,
          "Skylark APIs accessing compilation flags has been removed. "
              + "Use the new API on cc_common.");
    }
  }

  public void checkForLegacyLinkingApiAvailability() throws EvalException {
    if (cppOptions.disableLegacyLinkingApi) {
      throw new EvalException(
          null,
          "Skylark APIs accessing linking flags has been removed. Use the new API on cc_common.");
    }
  }

  public static PathFragment computeDefaultSysroot(String builtInSysroot) {
    if (builtInSysroot.isEmpty()) {
      return null;
    }
    if (!PathFragment.isNormalized(builtInSysroot)) {
      throw new IllegalArgumentException(
          "The built-in sysroot '" + builtInSysroot + "' is not normalized.");
    }
    return PathFragment.create(builtInSysroot);
  }

  boolean enableCcToolchainConfigInfoFromSkylark() {
    return cppOptions.enableCcToolchainConfigInfoFromSkylark;
  }

  /**
   * Returns the value of the libc top-level directory (--grte_top) as specified on the command line
   */
  public Label getLibcTopLabel() {
    return cppOptions.libcTopLabel;
  }
}
