blob: bd3d3b0409ff2dd9eef2a3723b4cd2a3a834adaa [file] [log] [blame]
// 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 static com.google.devtools.build.lib.rules.cpp.CcModule.isBuiltIn;
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.BuildConfigurationValue;
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.CoreOptions;
import com.google.devtools.build.lib.analysis.config.Fragment;
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.config.RequiresOptions;
import com.google.devtools.build.lib.analysis.starlark.annotations.StarlarkConfigurationField;
import com.google.devtools.build.lib.cmdline.BazelModuleContext;
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.rules.apple.AppleCommandLineOptions;
import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration.AppleCpus;
import com.google.devtools.build.lib.rules.apple.ApplePlatform;
import com.google.devtools.build.lib.starlarkbuildapi.cpp.CppConfigurationApi;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.EnumMap;
import javax.annotation.Nullable;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Module;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.StarlarkThread;
import net.starlark.java.eval.StarlarkValue;
/**
* This class represents the C/C++ parts of the {@link BuildConfigurationValue}, including the host
* architecture, target architecture, compiler version, and a standard library version.
*/
@Immutable
@RequiresOptions(options = {AppleCommandLineOptions.class, CppOptions.class})
public final class CppConfiguration extends 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";
/**
* Packages that can use the extended parameters in CppConfiguration See javadoc for {@link
* com.google.devtools.build.lib.rules.cpp.CcModule}
*/
public static final ImmutableList<String> EXPANDED_CC_CONFIGURATION_API_ALLOWLIST =
ImmutableList.of();
/** 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"),
LLVM_COV("llvm-cov"),
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 implements StarlarkValue {
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 PathFragment fdoPath;
private final Label fdoOptimizeLabel;
private final PathFragment csFdoAbsolutePath;
private final PathFragment propellerOptimizeAbsoluteCCProfile;
private final PathFragment propellerOptimizeAbsoluteLdProfile;
private final ImmutableList<String> conlyopts;
private final ImmutableList<String> copts;
private final ImmutableList<String> cxxopts;
private final ImmutableList<String> objcopts;
private final ImmutableList<String> linkopts;
private final ImmutableList<String> ltoindexOptions;
private final ImmutableList<String> ltobackendOptions;
private final CppOptions cppOptions;
// The dynamic mode for linking.
private final boolean stripBinaries;
private final CompilationMode compilationMode;
private final boolean collectCodeCoverage;
private final boolean isToolConfigurationDoNotUseWillBeRemovedFor129045294;
private final boolean appleGenerateDsym;
private final AppleBitcodeMode appleBitcodeMode;
public CppConfiguration(BuildOptions options) throws InvalidConfigurationException {
CppOptions cppOptions = options.get(CppOptions.class);
CoreOptions commonOptions = options.get(CoreOptions.class);
CompilationMode compilationMode = commonOptions.compilationMode;
ImmutableList.Builder<String> linkoptsBuilder = ImmutableList.builder();
linkoptsBuilder.addAll(cppOptions.linkoptList);
if (cppOptions.experimentalOmitfp) {
linkoptsBuilder.add("-Wl,--eh-frame-hdr");
}
PathFragment fdoPath = null;
Label fdoProfileLabel = null;
if (cppOptions.getFdoOptimize() != null) {
if (cppOptions.getFdoOptimize().startsWith("//")) {
try {
fdoProfileLabel = Label.parseAbsolute(cppOptions.getFdoOptimize(), ImmutableMap.of());
} catch (LabelSyntaxException e) {
throw new InvalidConfigurationException(e);
}
} else {
fdoPath = PathFragment.create(cppOptions.getFdoOptimize());
try {
// We don't check for file existence, but at least the filename should be well-formed.
FileSystemUtils.checkBaseName(fdoPath.getBaseName());
} catch (IllegalArgumentException e) {
throw new InvalidConfigurationException(e);
}
}
}
PathFragment csFdoAbsolutePath = null;
if (cppOptions.csFdoAbsolutePathForBuild != null) {
csFdoAbsolutePath = PathFragment.create(cppOptions.csFdoAbsolutePathForBuild);
if (!csFdoAbsolutePath.isAbsolute()) {
throw new InvalidConfigurationException(
"Path of '"
+ csFdoAbsolutePath.getPathString()
+ "' in --cs_fdo_absolute_path is not an absolute path.");
}
try {
FileSystemUtils.checkBaseName(csFdoAbsolutePath.getBaseName());
} catch (IllegalArgumentException e) {
throw new InvalidConfigurationException(e);
}
}
PathFragment propellerOptimizeAbsoluteCCProfile = null;
if (cppOptions.propellerOptimizeAbsoluteCCProfile != null) {
propellerOptimizeAbsoluteCCProfile =
PathFragment.create(cppOptions.propellerOptimizeAbsoluteCCProfile);
if (!propellerOptimizeAbsoluteCCProfile.isAbsolute()) {
throw new InvalidConfigurationException(
"Path of '"
+ propellerOptimizeAbsoluteCCProfile.getPathString()
+ "' in --propeller_optimize_absolute_cc_profile is not an absolute path.");
}
try {
FileSystemUtils.checkBaseName(propellerOptimizeAbsoluteCCProfile.getBaseName());
} catch (IllegalArgumentException e) {
throw new InvalidConfigurationException(e);
}
}
PathFragment propellerOptimizeAbsoluteLdProfile = null;
if (cppOptions.propellerOptimizeAbsoluteLdProfile != null) {
propellerOptimizeAbsoluteLdProfile =
PathFragment.create(cppOptions.propellerOptimizeAbsoluteLdProfile);
if (!propellerOptimizeAbsoluteLdProfile.isAbsolute()) {
throw new InvalidConfigurationException(
"Path of '"
+ propellerOptimizeAbsoluteLdProfile.getPathString()
+ "' in --propeller_optimize_absolute_ld_profile is not an absolute path.");
}
try {
FileSystemUtils.checkBaseName(propellerOptimizeAbsoluteLdProfile.getBaseName());
} catch (IllegalArgumentException e) {
throw new InvalidConfigurationException(e);
}
}
this.fdoPath = fdoPath;
this.fdoOptimizeLabel = fdoProfileLabel;
this.csFdoAbsolutePath = csFdoAbsolutePath;
this.propellerOptimizeAbsoluteCCProfile = propellerOptimizeAbsoluteCCProfile;
this.propellerOptimizeAbsoluteLdProfile = propellerOptimizeAbsoluteLdProfile;
this.conlyopts = ImmutableList.copyOf(cppOptions.conlyoptList);
this.copts = ImmutableList.copyOf(cppOptions.coptList);
this.cxxopts = ImmutableList.copyOf(cppOptions.cxxoptList);
this.objcopts = ImmutableList.copyOf(cppOptions.objcoptList);
this.linkopts = linkoptsBuilder.build();
this.ltoindexOptions = ImmutableList.copyOf(cppOptions.ltoindexoptList);
this.ltobackendOptions = ImmutableList.copyOf(cppOptions.ltobackendoptList);
this.cppOptions = cppOptions;
this.stripBinaries =
cppOptions.stripBinaries == StripMode.ALWAYS
|| (cppOptions.stripBinaries == StripMode.SOMETIMES
&& compilationMode == CompilationMode.FASTBUILD);
this.compilationMode = compilationMode;
this.collectCodeCoverage = commonOptions.collectCodeCoverage;
this.isToolConfigurationDoNotUseWillBeRemovedFor129045294 =
commonOptions.isHost || commonOptions.isExec;
this.appleGenerateDsym =
(cppOptions.appleGenerateDsym
|| (cppOptions.appleEnableAutoDsymDbg && compilationMode == CompilationMode.DBG));
this.appleBitcodeMode =
computeAppleBitcodeMode(options.get(AppleCommandLineOptions.class), commonOptions);
}
private static AppleBitcodeMode computeAppleBitcodeMode(
AppleCommandLineOptions options, CoreOptions commonOptions) {
ApplePlatform.PlatformType applePlatformType =
Preconditions.checkNotNull(options.applePlatformType, "applePlatformType");
AppleCpus appleCpus = AppleCpus.create(options, commonOptions);
EnumMap<ApplePlatform.PlatformType, AppleBitcodeMode> platformBitcodeModes =
AppleConfiguration.collectBitcodeModes(options.appleBitcodeMode);
return AppleConfiguration.getAppleBitcodeMode(
applePlatformType, appleCpus, platformBitcodeModes);
}
/** Returns the label of the <code>cc_compiler</code> rule for the C++ configuration. */
@StarlarkConfigurationField(
name = "cc_toolchain",
doc = "The label of the target describing the C++ toolchain",
defaultLabel = "//tools/cpp:crosstool",
defaultInToolRepository = true)
public Label getRuleProvidingCcToolchainProvider() {
return cppOptions.crosstoolTop;
}
/** Returns the configured current compilation mode. */
public CompilationMode getCompilationMode() {
return compilationMode;
}
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;
}
@StarlarkMethod(
name = "minimum_os_version",
doc = "The minimum OS version for C/C++ compilation.",
allowReturnNones = true)
@Nullable
public String getMinimumOsVersion() {
return cppOptions.minimumOsVersion;
}
/** Returns the value of the --dynamic_mode flag. */
public DynamicMode getDynamicModeFlag() {
return cppOptions.dynamicMode;
}
@StarlarkMethod(
name = "dynamic_mode",
doc = "Whether C/C++ binaries/tests were requested to be linked dynamically.")
public String getDynamicModeFlagString() {
return cppOptions.dynamicMode.name();
}
public boolean isFdo() {
return cppOptions.isFdo();
}
public boolean isCSFdo() {
return cppOptions.isCSFdo();
}
public boolean ignoreParamFile() {
return cppOptions.ignoreParamFile;
}
public boolean useArgsParamsFile() {
return cppOptions.useArgsParamsFile;
}
public boolean useCcTestFeature() {
return cppOptions.enableCcTestFeature;
}
@Override
public boolean useCcTestFeatureStarlark(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return useCcTestFeature();
}
/** 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);
}
@Override
public Sequence<String> getStripOptsStarlark(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return StarlarkList.immutableCopyOf(getStripOpts());
}
/** 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. */
@Override
@StarlarkConfigurationField(
name = "custom_malloc",
doc = "The label specified in --custom_malloc")
@Nullable
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;
}
@Override
public boolean buildTestDwpIsActivatedStarlark(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return buildTestDwpIsActivated();
}
/**
* 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;
}
/** @return value from --compiler option, null if the option was not passed. */
@Nullable
public String getCompilerFromOptions() {
return cppOptions.cppCompiler;
}
public boolean experimentalLinkStaticLibrariesOnce() {
return cppOptions.experimentalLinkStaticLibrariesOnce;
}
public boolean experimentalEnableTargetExportCheck() {
return cppOptions.experimentalEnableTargetExportCheck;
}
public boolean experimentalCcSharedLibraryDebug() {
return cppOptions.experimentalCcSharedLibraryDebug;
}
public boolean experimentalPlatformCcTest() {
return cppOptions.experimentalPlatformCcTest;
}
public boolean legacyWholeArchive() {
return cppOptions.legacyWholeArchive;
}
public boolean removeLegacyWholeArchive() {
return cppOptions.removeLegacyWholeArchive;
}
public boolean getInmemoryDotdFiles() {
return cppOptions.inmemoryDotdFiles;
}
public boolean getParseHeadersSkippedIfCorrespondingSrcsFound() {
return cppOptions.parseHeadersSkippedIfCorrespondingSrcsFound;
}
public boolean getUseInterfaceSharedLibraries() {
return cppOptions.useInterfaceSharedObjects;
}
/** 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() {
if (isOmitfp()) {
return ImmutableList.<String>builder()
.add("-fomit-frame-pointer")
.add("-fasynchronous-unwind-tables")
.add("-DNO_FRAME_POINTER")
.addAll(copts)
.build();
}
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 --objccopt option. */
@Override
public ImmutableList<String> getObjcopts() {
return objcopts;
}
/** 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(CoreOptions.class).isHost && cppOptions.isFdo()),
"FDO state should not propagate to the host configuration");
}
@Override
public String getOutputDirectoryName() {
// Add a tag that will be replaced with the CPU identifier.
String result = "{CPU}";
if (!cppOptions.outputDirectoryTag.isEmpty()) {
result += "-" + cppOptions.outputDirectoryTag;
}
return result;
}
/** Returns true if we should share identical native libraries between different targets. */
public boolean shareNativeDeps() {
return cppOptions.shareNativeDeps;
}
public boolean isStrictSystemIncludes() {
return cppOptions.strictSystemIncludes;
}
@Nullable
String getFdoInstrument() {
return cppOptions.fdoInstrumentForBuild;
}
PathFragment getFdoPath() {
return fdoPath;
}
Label getFdoOptimizeLabel() {
return fdoOptimizeLabel;
}
public String getCSFdoInstrument() {
return cppOptions.csFdoInstrumentForBuild;
}
public PathFragment getCSFdoAbsolutePath() {
return csFdoAbsolutePath;
}
public PathFragment getPropellerOptimizeAbsoluteCCProfile() {
return propellerOptimizeAbsoluteCCProfile;
}
public PathFragment getPropellerOptimizeAbsoluteLdProfile() {
return propellerOptimizeAbsoluteLdProfile;
}
@Nullable
Label getFdoPrefetchHintsLabel() {
return cppOptions.getFdoPrefetchHintsLabel();
}
Label getFdoProfileLabel() {
return cppOptions.fdoProfileLabel;
}
public Label getCSFdoProfileLabel() {
return cppOptions.csFdoProfileLabel;
}
@Nullable
Label getPropellerOptimizeLabel() {
if (cppOptions.fdoInstrumentForBuild != null || cppOptions.csFdoInstrumentForBuild != null) {
return null;
}
return cppOptions.getPropellerOptimizeLabel();
}
@Nullable
Label getXFdoProfileLabel() {
if (cppOptions.fdoOptimizeForBuild != null
|| cppOptions.fdoInstrumentForBuild != null
|| cppOptions.fdoProfileLabel != null
|| collectCodeCoverage) {
return null;
}
return cppOptions.xfdoProfileLabel;
}
public boolean isFdoAbsolutePathEnabled() {
return cppOptions.enableFdoProfileAbsolutePath;
}
public boolean useLLVMCoverageMapFormat() {
return cppOptions.useLLVMCoverageMapFormat;
}
public boolean removeCpuCompilerCcToolchainAttributes() {
return cppOptions.removeCpuCompilerCcToolchainAttributes;
}
@Nullable
public static PathFragment computeDefaultSysroot(String builtInSysroot) {
if (builtInSysroot.isEmpty()) {
return null;
}
return PathFragment.create(builtInSysroot);
}
/**
* Returns the value of the libc top-level directory (--grte_top) as specified on the command line
*/
public Label getLibcTopLabel() {
return cppOptions.libcTopLabel;
}
@Override
public Label getLibcTopLabelStarlark(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return getLibcTopLabel();
}
@Override
public boolean shareNativeDepsStarlark(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return shareNativeDeps();
}
/**
* Returns the value of the libc top-level directory (--grte_top) as specified on the command line
*/
@Nullable
public Label getTargetLibcTopLabel() {
if (!isToolConfigurationDoNotUseWillBeRemovedFor129045294) {
// This isn't for a platform-enabled C++ toolchain (legacy C++ toolchains evaluate in the
// target configuration while platform-enabled toolchains evaluate in the host/exec
// configuration). targetLibcTopLabel is only intended for platform-enabled toolchains and can
// cause errors otherwise.
//
// For example: if a legacy-configured toolchain inherits a --grte_top pointing to an Android
// runtime alias that select()s on a target Android CPU and an iOS dep changes the CPU to an
// iOS CPU, the alias resolution fails. Legacy toolchains should read --grte_top through
// libcTopLabel (which changes along with the iOS CPU change), not this.
return null;
}
return cppOptions.targetLibcTopLabel;
}
@StarlarkMethod(name = "enable_legacy_cc_provider", documented = false, useStarlarkThread = true)
public boolean enableLegacyCcProviderForStarlark(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return enableLegacyCcProvider();
}
public boolean enableLegacyCcProvider() {
return !cppOptions.disableLegacyCcProvider;
}
public boolean dontEnableHostNonhost() {
return cppOptions.dontEnableHostNonhost;
}
public boolean requireCtxInConfigureFeatures() {
return cppOptions.requireCtxInConfigureFeatures;
}
public boolean collectCodeCoverage() {
return collectCodeCoverage;
}
public boolean enableCcToolchainResolution() {
return cppOptions.enableCcToolchainResolution;
}
public boolean saveFeatureState() {
return cppOptions.saveFeatureState;
}
public boolean useStandaloneLtoIndexingCommandLines() {
return cppOptions.useStandaloneLtoIndexingCommandLines;
}
public boolean useSpecificToolFiles() {
return cppOptions.useSpecificToolFiles;
}
public boolean disableNoCopts() {
return cppOptions.disableNoCopts;
}
public boolean loadCcRulesFromBzl() {
return cppOptions.loadCcRulesFromBzl;
}
public boolean validateTopLevelHeaderInclusions() {
return cppOptions.validateTopLevelHeaderInclusions;
}
@Override
public boolean appleGenerateDsym() {
return appleGenerateDsym;
}
public boolean experimentalStarlarkCcImport() {
return cppOptions.experimentalStarlarkCcImport;
}
public boolean strictHeaderCheckingFromStarlark() {
return cppOptions.forceStrictHeaderCheckFromStarlark;
}
public boolean useCppCompileHeaderMnemonic() {
return cppOptions.useCppCompileHeaderMnemonic;
}
public boolean generateLlvmLCov() {
return cppOptions.generateLlvmLcov;
}
public boolean experimentalIncludeScanning() {
return cppOptions.experimentalIncludeScanning;
}
public boolean objcShouldScanIncludes() {
return cppOptions.objcScanIncludes;
}
public boolean objcShouldGenerateDotdFiles() {
return cppOptions.objcGenerateDotdFiles;
}
@Override
public boolean objcGenerateLinkmap() {
return cppOptions.objcGenerateLinkmap;
}
public boolean objcEnableBinaryStripping() {
return cppOptions.objcEnableBinaryStripping;
}
@StarlarkMethod(
name = "experimental_cc_implementation_deps",
documented = false,
useStarlarkThread = true)
public boolean experimentalCcImplementationDepsForStarlark(StarlarkThread thread)
throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return experimentalCcImplementationDeps();
}
public boolean experimentalCcImplementationDeps() {
return cppOptions.experimentalCcImplementationDeps;
}
public boolean getExperimentalCppCompileResourcesEstimation() {
return cppOptions.experimentalCppCompileResourcesEstimation;
}
@Override
public boolean macosSetInstallName() {
return cppOptions.macosSetInstallName;
}
private static void checkInExpandedApiAllowlist(StarlarkThread thread, String feature)
throws EvalException {
String rulePackage =
((BazelModuleContext) Module.ofInnermostEnclosingStarlarkFunction(thread).getClientData())
.label()
.getPackageName();
if (!isBuiltIn(thread) && !EXPANDED_CC_CONFIGURATION_API_ALLOWLIST.contains(rulePackage)) {
throw Starlark.errorf(
"Rule in '%s' cannot use '%s' in CppConfiguration", rulePackage, feature);
}
}
@Override
public boolean forcePicStarlark(StarlarkThread thread) throws EvalException {
checkInExpandedApiAllowlist(thread, "force_pic");
return forcePic();
}
@Override
public boolean generateLlvmLcovStarlark(StarlarkThread thread) throws EvalException {
checkInExpandedApiAllowlist(thread, "generate_llvm_lcov");
return generateLlvmLCov();
}
@Override
public String fdoInstrumentStarlark(StarlarkThread thread) throws EvalException {
checkInExpandedApiAllowlist(thread, "fdo_instrument");
return getFdoInstrument();
}
@Override
public boolean processHeadersInDependenciesStarlark(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return processHeadersInDependencies();
}
@Override
public boolean saveFeatureStateStarlark(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return saveFeatureState();
}
@Override
public boolean fissionActiveForCurrentCompilationModeStarlark(StarlarkThread thread)
throws EvalException {
checkInExpandedApiAllowlist(thread, "fission_active_for_current_compilation_mode");
return fissionIsActiveForCurrentCompilationMode();
}
@Override
public boolean getExperimentalLinkStaticLibrariesOnce(StarlarkThread thread)
throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return experimentalLinkStaticLibrariesOnce();
}
@Override
public boolean getExperimentalEnableTargetExportCheck(StarlarkThread thread)
throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return experimentalEnableTargetExportCheck();
}
@Override
public boolean getExperimentalCcSharedLibraryDebug(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return experimentalCcSharedLibraryDebug();
}
@Override
public boolean getExperimentalPlatformCcTest(StarlarkThread thread) throws EvalException {
CcModule.checkPrivateStarlarkificationAllowlist(thread);
return experimentalPlatformCcTest();
}
/**
* Returns the bitcode mode to use for compilation.
*
* <p>Users can control bitcode mode using the {@code apple_bitcode} build flag, but bitcode will
* be disabled for all simulator architectures regardless of this flag.
*/
@Override
public AppleBitcodeMode getAppleBitcodeMode() {
return appleBitcodeMode;
}
@Override
public boolean objcShouldStripBinary() {
return objcEnableBinaryStripping() && getCompilationMode() == CompilationMode.OPT;
}
}