blob: 141f84b9a3c9cb066062738f23f7d9a75476e2af [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 com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
import com.google.devtools.build.lib.rules.cpp.FdoProvider.FdoMode;
import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcToolchainProviderApi;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
import java.util.Map;
import javax.annotation.Nullable;
/** Information about a C++ compiler used by the <code>cc_*</code> rules. */
@Immutable
@AutoCodec
public final class CcToolchainProvider extends ToolchainInfo implements CcToolchainProviderApi {
public static final String SKYLARK_NAME = "CcToolchainInfo";
/** An empty toolchain to be returned in the error case (instead of null). */
public static final CcToolchainProvider EMPTY_TOOLCHAIN_IS_ERROR =
new CcToolchainProvider(
/* values= */ ImmutableMap.of(),
/* cppConfiguration= */ null,
/* toolchainInfo= */ null,
/* crosstoolTopPathFragment= */ null,
/* crosstool= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* crosstoolMiddleman= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* compile= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* compileWithoutIncludes= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* strip= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* objCopy= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* as= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* ar= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* link= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* interfaceSoBuilder= */ null,
/* dwp= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* coverage= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* libcLink= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* staticRuntimeLinkInputs= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* staticRuntimeLinkMiddleman= */ null,
/* dynamicRuntimeLinkInputs= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
/* dynamicRuntimeLinkMiddleman= */ null,
/* dynamicRuntimeSolibDir= */ PathFragment.EMPTY_FRAGMENT,
CcCompilationContext.EMPTY,
/* supportsParamFiles= */ false,
/* supportsHeaderParsing= */ false,
CcToolchainVariables.EMPTY,
/* builtinIncludeFiles= */ ImmutableList.of(),
/* coverageEnvironment= */ NestedSetBuilder.emptySet(Order.COMPILE_ORDER),
/* linkDynamicLibraryTool= */ null,
/* builtInIncludeDirectories= */ ImmutableList.of(),
/* sysroot= */ null,
FdoMode.OFF,
/* fdoProvider= */ null,
/* useLLVMCoverageMapFormat= */ false,
/* codeCoverageEnabled= */ false,
/* isHostConfiguration= */ false);
@Nullable private final CppConfiguration cppConfiguration;
private final CppToolchainInfo toolchainInfo;
private final PathFragment crosstoolTopPathFragment;
private final NestedSet<Artifact> crosstool;
private final NestedSet<Artifact> crosstoolMiddleman;
private final NestedSet<Artifact> compile;
private final NestedSet<Artifact> compileWithoutIncludes;
private final NestedSet<Artifact> strip;
private final NestedSet<Artifact> objCopy;
private final NestedSet<Artifact> as;
private final NestedSet<Artifact> ar;
private final NestedSet<Artifact> link;
private final Artifact interfaceSoBuilder;
private final NestedSet<Artifact> dwp;
private final NestedSet<Artifact> coverage;
private final NestedSet<Artifact> libcLink;
private final NestedSet<Artifact> staticRuntimeLinkInputs;
@Nullable private final Artifact staticRuntimeLinkMiddleman;
private final NestedSet<Artifact> dynamicRuntimeLinkInputs;
@Nullable private final Artifact dynamicRuntimeLinkMiddleman;
private final PathFragment dynamicRuntimeSolibDir;
private final CcCompilationInfo ccCompilationInfo;
private final boolean supportsParamFiles;
private final boolean supportsHeaderParsing;
private final CcToolchainVariables buildVariables;
private final ImmutableList<Artifact> builtinIncludeFiles;
private final NestedSet<Pair<String, String>> coverageEnvironment;
@Nullable private final Artifact linkDynamicLibraryTool;
private final ImmutableList<PathFragment> builtInIncludeDirectories;
@Nullable private final PathFragment sysroot;
private final FdoMode fdoMode;
private final boolean useLLVMCoverageMapFormat;
private final boolean codeCoverageEnabled;
private final boolean isHostConfiguration;
private final boolean forcePic;
private final boolean shouldStripBinaries;
/**
* WARNING: We don't like {@link FdoProvider}. Its {@link FdoProvider#fdoProfilePath} is pure
* path and that is horrible as it breaks many Bazel assumptions! Don't do bad stuff with it,
* don't take inspiration from it.
*/
private final FdoProvider fdoProvider;
public CcToolchainProvider(
ImmutableMap<String, Object> values,
@Nullable CppConfiguration cppConfiguration,
CppToolchainInfo toolchainInfo,
PathFragment crosstoolTopPathFragment,
NestedSet<Artifact> crosstool,
NestedSet<Artifact> crosstoolMiddleman,
NestedSet<Artifact> compile,
NestedSet<Artifact> compileWithoutIncludes,
NestedSet<Artifact> strip,
NestedSet<Artifact> objCopy,
NestedSet<Artifact> as,
NestedSet<Artifact> ar,
NestedSet<Artifact> link,
Artifact interfaceSoBuilder,
NestedSet<Artifact> dwp,
NestedSet<Artifact> coverage,
NestedSet<Artifact> libcLink,
NestedSet<Artifact> staticRuntimeLinkInputs,
@Nullable Artifact staticRuntimeLinkMiddleman,
NestedSet<Artifact> dynamicRuntimeLinkInputs,
@Nullable Artifact dynamicRuntimeLinkMiddleman,
PathFragment dynamicRuntimeSolibDir,
CcCompilationContext ccCompilationContext,
boolean supportsParamFiles,
boolean supportsHeaderParsing,
CcToolchainVariables buildVariables,
ImmutableList<Artifact> builtinIncludeFiles,
NestedSet<Pair<String, String>> coverageEnvironment,
Artifact linkDynamicLibraryTool,
ImmutableList<PathFragment> builtInIncludeDirectories,
@Nullable PathFragment sysroot,
FdoMode fdoMode,
FdoProvider fdoProvider,
boolean useLLVMCoverageMapFormat,
boolean codeCoverageEnabled,
boolean isHostConfiguration) {
super(values, Location.BUILTIN);
this.cppConfiguration = cppConfiguration;
this.toolchainInfo = toolchainInfo;
this.crosstoolTopPathFragment = crosstoolTopPathFragment;
this.crosstool = Preconditions.checkNotNull(crosstool);
this.crosstoolMiddleman = Preconditions.checkNotNull(crosstoolMiddleman);
this.compile = Preconditions.checkNotNull(compile);
this.compileWithoutIncludes = Preconditions.checkNotNull(compileWithoutIncludes);
this.strip = Preconditions.checkNotNull(strip);
this.objCopy = Preconditions.checkNotNull(objCopy);
this.as = Preconditions.checkNotNull(as);
this.ar = Preconditions.checkNotNull(ar);
this.link = Preconditions.checkNotNull(link);
this.interfaceSoBuilder = interfaceSoBuilder;
this.dwp = Preconditions.checkNotNull(dwp);
this.coverage = Preconditions.checkNotNull(coverage);
this.libcLink = Preconditions.checkNotNull(libcLink);
this.staticRuntimeLinkInputs = Preconditions.checkNotNull(staticRuntimeLinkInputs);
this.staticRuntimeLinkMiddleman = staticRuntimeLinkMiddleman;
this.dynamicRuntimeLinkInputs = Preconditions.checkNotNull(dynamicRuntimeLinkInputs);
this.dynamicRuntimeLinkMiddleman = dynamicRuntimeLinkMiddleman;
this.dynamicRuntimeSolibDir = Preconditions.checkNotNull(dynamicRuntimeSolibDir);
this.ccCompilationInfo =
new CcCompilationInfo(Preconditions.checkNotNull(ccCompilationContext));
this.supportsParamFiles = supportsParamFiles;
this.supportsHeaderParsing = supportsHeaderParsing;
this.buildVariables = buildVariables;
this.builtinIncludeFiles = builtinIncludeFiles;
this.coverageEnvironment = coverageEnvironment;
this.linkDynamicLibraryTool = linkDynamicLibraryTool;
this.builtInIncludeDirectories = builtInIncludeDirectories;
this.sysroot = sysroot;
this.fdoMode = fdoMode;
this.fdoProvider = fdoProvider;
this.useLLVMCoverageMapFormat = useLLVMCoverageMapFormat;
this.codeCoverageEnabled = codeCoverageEnabled;
this.isHostConfiguration = isHostConfiguration;
if (cppConfiguration != null) {
this.forcePic = cppConfiguration.forcePic();
this.shouldStripBinaries = cppConfiguration.shouldStripBinaries();
} else {
this.forcePic = false;
this.shouldStripBinaries = false;
}
}
/** Returns c++ Make variables. */
public static Map<String, String> getCppBuildVariables(
Function<Tool, PathFragment> getToolPathFragment,
String targetLibc,
String compiler,
String targetCpu,
PathFragment crosstoolTopPathFragment,
String abiGlibcVersion,
String abi,
Map<String, String> additionalMakeVariables) {
ImmutableMap.Builder<String, String> result = ImmutableMap.builder();
// hardcoded CC->gcc setting for unit tests
result.put("CC", getToolPathFragment.apply(Tool.GCC).getPathString());
// Make variables provided by crosstool/gcc compiler suite.
result.put("AR", getToolPathFragment.apply(Tool.AR).getPathString());
result.put("NM", getToolPathFragment.apply(Tool.NM).getPathString());
result.put("LD", getToolPathFragment.apply(Tool.LD).getPathString());
PathFragment objcopyTool = getToolPathFragment.apply(Tool.OBJCOPY);
if (objcopyTool != null) {
// objcopy is optional in Crosstool
result.put("OBJCOPY", objcopyTool.getPathString());
}
result.put("STRIP", getToolPathFragment.apply(Tool.STRIP).getPathString());
PathFragment gcovtool = getToolPathFragment.apply(Tool.GCOVTOOL);
if (gcovtool != null) {
// gcov-tool is optional in Crosstool
result.put("GCOVTOOL", gcovtool.getPathString());
}
if (targetLibc.startsWith("glibc-")) {
result.put("GLIBC_VERSION", targetLibc.substring("glibc-".length()));
} else {
result.put("GLIBC_VERSION", targetLibc);
}
result.put("C_COMPILER", compiler);
// Deprecated variables
// TODO(bazel-team): delete all of these.
result.put("CROSSTOOLTOP", crosstoolTopPathFragment.getPathString());
// TODO(kmensah): Remove when skylark dependencies can be updated to rely on
// CcToolchainProvider.
result.putAll(additionalMakeVariables);
result.put("ABI_GLIBC_VERSION", abiGlibcVersion);
result.put("ABI", abi);
return result.build();
}
/**
* Determines if we should apply -fPIC for this rule's C++ compilations. This determination is
* generally made by the global C++ configuration settings "needsPic" and "usePicForBinaries".
* However, an individual rule may override these settings by applying -fPIC" to its "nocopts"
* attribute. This allows incompatible rules to "opt out" of global PIC settings (see bug:
* "Provide a way to turn off -fPIC for targets that can't be built that way").
*
* @return true if this rule's compilations should apply -fPIC, false otherwise
*/
@Override
public boolean usePicForDynamicLibraries() {
return forcePic || toolchainNeedsPic();
}
/**
* Returns true if Fission is specified and supported by the CROSSTOOL for the build implied by
* the given configuration and toolchain.
*/
public boolean useFission() {
return Preconditions.checkNotNull(cppConfiguration).fissionIsActiveForCurrentCompilationMode()
&& supportsFission();
}
/** Whether the toolchains supports header parsing. */
public boolean supportsHeaderParsing() {
return supportsHeaderParsing;
}
/**
* Returns true if headers should be parsed in this build.
*
* <p>This means headers in 'srcs' and 'hdrs' will be "compiled" using {@link CppCompileAction}).
* It will run compiler's parser to ensure the header is self-contained. This is required for
* layering_check to work.
*/
public boolean shouldProcessHeaders(FeatureConfiguration featureConfiguration) {
// If parse_headers_verifies_modules is switched on, we verify that headers are
// self-contained by building the module instead.
return !cppConfiguration.getParseHeadersVerifiesModules()
&& featureConfiguration.isEnabled(CppRuleClasses.PARSE_HEADERS);
}
/**
* Returns true if Fission and PER_OBJECT_DEBUG_INFO are specified and supported by the CROSSTOOL
* for the build implied by the given configuration, toolchain and feature configuration.
*/
public boolean shouldCreatePerObjectDebugInfo(FeatureConfiguration featureConfiguration) {
return useFission() && featureConfiguration.isEnabled(CppRuleClasses.PER_OBJECT_DEBUG_INFO);
}
@Override
public void addGlobalMakeVariables(ImmutableMap.Builder<String, String> globalMakeEnvBuilder) {
globalMakeEnvBuilder.putAll(
getCppBuildVariables(
this::getToolPathFragment,
getTargetLibc(),
getCompiler(),
getTargetCpu(),
crosstoolTopPathFragment,
getAbiGlibcVersion(),
getAbi(),
getAdditionalMakeVariables()));
}
@Override
public ImmutableList<String> getBuiltInIncludeDirectoriesAsStrings() {
return builtInIncludeDirectories
.stream()
.map(PathFragment::getSafePathString)
.collect(ImmutableList.toImmutableList());
}
public ImmutableList<PathFragment> getBuiltInIncludeDirectories() {
return builtInIncludeDirectories;
}
/** Returns the identifier of the toolchain as specified in the {@code CToolchain} proto. */
public String getToolchainIdentifier() {
return toolchainInfo.getToolchainIdentifier();
}
/**
* Returns all the files in Crosstool. Is not a middleman.
*/
public NestedSet<Artifact> getCrosstool() {
return crosstool;
}
/**
* Returns a middleman for all the files in Crosstool.
*/
public NestedSet<Artifact> getCrosstoolMiddleman() {
return crosstoolMiddleman;
}
/**
* Returns the files necessary for compilation.
*/
public NestedSet<Artifact> getCompile() {
return compile;
}
/**
* Returns the files necessary for compilation excluding headers, assuming that included files
* will be discovered by input discovery. If the toolchain does not provide this fileset, falls
* back to {@link #getCompile()}.
*/
public NestedSet<Artifact> getCompileWithoutIncludes() {
if (compileWithoutIncludes.isEmpty()) {
return getCompile();
}
return compileWithoutIncludes;
}
/**
* Returns the files necessary for a 'strip' invocation.
*/
public NestedSet<Artifact> getStrip() {
return strip;
}
/**
* Returns the files necessary for an 'objcopy' invocation.
*/
public NestedSet<Artifact> getObjcopy() {
return objCopy;
}
/**
* Returns the files necessary for an 'as' invocation. May be empty if the CROSSTOOL
* file does not define as_files.
*/
public NestedSet<Artifact> getAs() {
return as;
}
/**
* Returns the files necessary for an 'ar' invocation. May be empty if the CROSSTOOL
* file does not define ar_files.
*/
public NestedSet<Artifact> getAr() {
return ar;
}
/**
* Returns the files necessary for linking, including the files needed for libc.
*/
public NestedSet<Artifact> getLink() {
return link;
}
public NestedSet<Artifact> getDwp() {
return dwp;
}
/**
* Returns the files necessary for capturing code coverage.
*/
public NestedSet<Artifact> getCoverage() {
return coverage;
}
public NestedSet<Artifact> getLibcLink() {
return libcLink;
}
/**
* Returns true if the featureConfiguration includes statically linking the cpp runtimes.
*
* @param featureConfiguration the relevant FeatureConfiguration.
*/
public boolean shouldStaticallyLinkCppRuntimes(FeatureConfiguration featureConfiguration) {
return featureConfiguration.isEnabled(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES);
}
/** Returns the static runtime libraries. */
public NestedSet<Artifact> getStaticRuntimeLinkInputs(FeatureConfiguration featureConfiguration) {
if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
return staticRuntimeLinkInputs;
} else {
return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
}
}
/** Returns an aggregating middleman that represents the static runtime libraries. */
@Nullable
public Artifact getStaticRuntimeLinkMiddleman(FeatureConfiguration featureConfiguration) {
if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
return staticRuntimeLinkMiddleman;
} else {
return null;
}
}
/** Returns the dynamic runtime libraries. */
public NestedSet<Artifact> getDynamicRuntimeLinkInputs(
FeatureConfiguration featureConfiguration) {
if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
return dynamicRuntimeLinkInputs;
} else {
return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
}
}
/** Returns an aggregating middleman that represents the dynamic runtime libraries. */
@Nullable
public Artifact getDynamicRuntimeLinkMiddleman(FeatureConfiguration featureConfiguration) {
if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
return dynamicRuntimeLinkMiddleman;
} else {
return null;
}
}
/**
* Returns the name of the directory where the solib symlinks for the dynamic runtime libraries
* live. The directory itself will be under the root of the host configuration in the 'bin'
* directory.
*/
public PathFragment getDynamicRuntimeSolibDir() {
return dynamicRuntimeSolibDir;
}
/** Returns the {@code CcCompilationContext} for the toolchain. */
public CcCompilationContext getCcCompilationContext() {
return ccCompilationInfo.getCcCompilationContext();
}
/** Returns the {@code CcCompilationContext} for the toolchain. */
public CcCompilationInfo getCcCompilationInfo() {
return ccCompilationInfo;
}
/**
* Whether the toolchains supports parameter files.
*/
public boolean supportsParamFiles() {
return supportsParamFiles;
}
/**
* Returns the configured features of the toolchain.
*/
@Nullable
public CcToolchainFeatures getFeatures() {
return toolchainInfo.getFeatures();
}
public Label getCcToolchainLabel() {
return toolchainInfo.getCcToolchainLabel();
}
/**
* Returns whether shared libraries must be compiled with position independent code on this
* platform.
*/
public boolean toolchainNeedsPic() {
return toolchainInfo.toolchainNeedsPic();
}
/**
* Returns the run time sysroot, which is where the dynamic linker and system libraries are found
* at runtime. This is usually an absolute path. If the toolchain compiler does not support
* sysroots, then this method returns <code>null</code>.
*/
public PathFragment getRuntimeSysroot() {
return toolchainInfo.getRuntimeSysroot();
}
/**
* Return the name of the directory (relative to the bin directory) that holds mangled links to
* shared libraries. This name is always set to the '{@code _solib_<cpu_archictecture_name>}.
*/
public String getSolibDirectory() {
return toolchainInfo.getSolibDirectory();
}
/**
* Returns the compilation mode.
*/
@Nullable
public CompilationMode getCompilationMode() {
return cppConfiguration == null ? null : cppConfiguration.getCompilationMode();
}
/**
* Returns whether the toolchain supports the gold linker.
*/
public boolean supportsGoldLinker() {
return toolchainInfo.supportsGoldLinker();
}
/**
* Returns whether the toolchain supports dynamic linking.
*/
public boolean supportsDynamicLinker() {
return toolchainInfo.supportsDynamicLinker();
}
/**
* Returns whether the toolchain supports linking C/C++ runtime libraries
* supplied inside the toolchain distribution.
*/
public boolean supportsEmbeddedRuntimes() {
return toolchainInfo.supportsEmbeddedRuntimes();
}
/**
* Returns whether the toolchain supports EXEC_ORIGIN libraries resolution.
*/
public boolean supportsExecOrigin() {
// We're rolling out support for this in the same release that also supports embedded runtimes.
return toolchainInfo.supportsEmbeddedRuntimes();
}
/** Returns whether the toolchain supports the --start-lib/--end-lib options. */
public boolean supportsStartEndLib() {
return toolchainInfo.supportsStartEndLib();
}
/**
* Returns whether this toolchain supports interface shared objects.
*
* <p>Should be true if this toolchain generates ELF objects.
*/
public boolean supportsInterfaceSharedObjects() {
return toolchainInfo.supportsInterfaceSharedObjects();
}
@Nullable
public CppConfiguration getCppConfiguration() {
return cppConfiguration;
}
/** Returns build variables to be templated into the crosstool. */
public CcToolchainVariables getBuildVariables() {
return buildVariables;
}
/**
* Return the set of include files that may be included even if they are not mentioned in the
* source file or any of the headers included by it.
*/
public ImmutableList<Artifact> getBuiltinIncludeFiles() {
return builtinIncludeFiles;
}
/**
* Returns the environment variables that need to be added to tests that collect code coverage.
*/
public NestedSet<Pair<String, String>> getCoverageEnvironment() {
return coverageEnvironment;
}
/**
* Returns the tool which should be used for linking dynamic libraries, or in case it's not
* specified by the crosstool this will be @tools_repository/tools/cpp:link_dynamic_library
*/
public Artifact getLinkDynamicLibraryTool() {
return linkDynamicLibraryTool;
}
/**
* Returns the tool that builds interface libraries from dynamic libraries.
*/
public Artifact getInterfaceSoBuilder() {
return interfaceSoBuilder;
}
@Override
public String getSysroot() {
return sysroot != null ? sysroot.getPathString() : null;
}
/**
* Returns the path fragment that is either absolute or relative to the execution root that can be
* used to execute the given tool.
*/
public PathFragment getToolPathFragment(CppConfiguration.Tool tool) {
return toolchainInfo.getToolPathFragment(tool);
}
/**
* Returns the abi we're using, which is a gcc version. E.g.: "gcc-3.4". Note that in practice we
* might be using gcc-3.4 as ABI even when compiling with gcc-4.1.0, because ABIs are backwards
* compatible.
*/
// TODO(bazel-team): The javadoc should clarify how this is used in Blaze.
public String getAbi() {
return toolchainInfo.getAbi();
}
/**
* Returns the glibc version used by the abi we're using. This is a glibc version number (e.g.,
* "2.2.2"). Note that in practice we might be using glibc 2.2.2 as ABI even when compiling with
* gcc-4.2.2, gcc-4.3.1, or gcc-4.4.0 (which use glibc 2.3.6), because ABIs are backwards
* compatible.
*/
// TODO(bazel-team): The javadoc should clarify how this is used in Blaze.
public String getAbiGlibcVersion() {
return toolchainInfo.getAbiGlibcVersion();
}
/**
* Returns a label that references the library files needed to statically
* link the C++ runtime (i.e. libgcc.a, libgcc_eh.a, libstdc++.a) for the
* target architecture.
*/
public Label getStaticRuntimeLibsLabel() {
return toolchainInfo.getStaticRuntimeLibsLabel();
}
/**
* Returns a label that references the library files needed to dynamically
* link the C++ runtime (i.e. libgcc_s.so, libstdc++.so) for the target
* architecture.
*/
public Label getDynamicRuntimeLibsLabel() {
return toolchainInfo.getDynamicRuntimeLibsLabel();
}
/** Returns the compiler version string (e.g. "gcc-4.1.1"). */
@Override
public String getCompiler() {
return toolchainInfo == null ? null : toolchainInfo.getCompiler();
}
/** Returns the libc version string (e.g. "glibc-2.2.2"). */
@Override
public String getTargetLibc() {
return toolchainInfo == null ? null : toolchainInfo.getTargetLibc();
}
/** Returns the target architecture using blaze-specific constants (e.g. "piii"). */
@Override
public String getTargetCpu() {
return toolchainInfo == null ? null : toolchainInfo.getTargetCpu();
}
/**
* 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 toolchainInfo.getAdditionalMakeVariables();
}
public FdoProvider getFdoProvider() {
return fdoProvider;
}
/**
* Returns whether the toolchain supports "Fission" C++ builds, i.e. builds where compilation
* partitions object code and debug symbols into separate output files.
*/
public boolean supportsFission() {
return toolchainInfo.supportsFission();
}
@Override
// TODO(b/24373706): Remove this method once new C++ toolchain API is available
public ImmutableList<String> getUnfilteredCompilerOptionsWithSysroot(
Iterable<String> featuresNotUsedAnymore) throws EvalException {
cppConfiguration.checkForLegacyCompilationApiAvailability();
return toolchainInfo.getUnfilteredCompilerOptions(sysroot);
}
public ImmutableList<String> getUnfilteredCompilerOptions() {
return toolchainInfo.getUnfilteredCompilerOptions(/* sysroot= */ null);
}
/**
* Unused, for compatibility with things internal to Google.
*
* <p>Deprecated: Use platforms.
*/
@Deprecated
public String getTargetOS() {
return toolchainInfo.getTargetOS();
}
@Override
public ImmutableList<String> getLinkOptionsWithSysroot() throws EvalException {
if (cppConfiguration == null) {
return ImmutableList.of();
}
cppConfiguration.checkForLegacyLinkingApiAvailability();
return cppConfiguration.getLinkOptionsDoNotUse(sysroot);
}
public ImmutableList<String> getLinkOptions() {
return cppConfiguration.getLinkOptionsDoNotUse(/* sysroot= */ null);
}
/**
* Returns test-only link options such that certain test-specific features can be configured
* separately (e.g. lazy binding).
*/
public ImmutableList<String> getTestOnlyLinkOptions() {
return toolchainInfo.getTestOnlyLinkOptions();
}
/** Returns the system name which is required by the toolchain to run. */
public String getHostSystemName() {
return toolchainInfo.getHostSystemName();
}
/**
* Returns the list of options to be used with 'objcopy' when converting binary files to object
* files, or {@code null} if this operation is not supported.
*/
public ImmutableList<String> getObjCopyOptionsForEmbedding() {
return toolchainInfo.getObjCopyOptionsForEmbedding();
}
/**
* Returns the list of options to be used with 'ld' when converting binary files to object files,
* or {@code null} if this operation is not supported.
*/
public ImmutableList<String> getLdOptionsForEmbedding() {
return toolchainInfo.getLdOptionsForEmbedding();
}
/**
* Returns link options for the specified flag list, combined with universal options for all
* shared libraries (regardless of link staticness).
*/
ImmutableList<String> getSharedLibraryLinkOptions(ImmutableList<String> flags) {
return toolchainInfo.getSharedLibraryLinkOptions(flags);
}
/** Returns compiler flags arising from the {@link CToolchain}. */
ImmutableList<String> getToolchainCompilerFlags() {
return toolchainInfo.getCompilerFlags();
}
/** Returns additional compiler flags for C++ arising from the {@link CToolchain} */
ImmutableList<String> getToolchainCxxFlags() {
return toolchainInfo.getCxxFlags();
}
/**
* Returns compiler flags arising from the {@link CToolchain} for C compilation by compilation
* mode.
*/
ImmutableListMultimap<CompilationMode, String> getCFlagsByCompilationMode() {
return toolchainInfo.getCFlagsByCompilationMode();
}
/**
* Returns compiler flags arising from the {@link CToolchain} for C++ compilation by compilation
* mode.
*/
ImmutableListMultimap<CompilationMode, String> getCxxFlagsByCompilationMode() {
return toolchainInfo.getCxxFlagsByCompilationMode();
}
/** Returns linker flags for fully statically linked outputs. */
ImmutableList<String> getLegacyFullyStaticLinkFlags(CompilationMode compilationMode) {
return configureAllLegacyLinkOptions(compilationMode, LinkingMode.LEGACY_FULLY_STATIC);
}
/** Returns linker flags for mostly static linked outputs. */
ImmutableList<String> getLegacyMostlyStaticLinkFlags(CompilationMode compilationMode) {
return configureAllLegacyLinkOptions(compilationMode, LinkingMode.STATIC);
}
/** Returns linker flags for mostly static shared linked outputs. */
ImmutableList<String> getLegacyMostlyStaticSharedLinkFlags(CompilationMode compilationMode) {
return configureAllLegacyLinkOptions(
compilationMode, LinkingMode.LEGACY_MOSTLY_STATIC_LIBRARIES);
}
/** Returns linker flags for artifacts that are not fully or mostly statically linked. */
ImmutableList<String> getLegacyDynamicLinkFlags(CompilationMode compilationMode) {
return configureAllLegacyLinkOptions(compilationMode, LinkingMode.DYNAMIC);
}
/**
* Return all flags coming from naked {@code linker_flag} fields in the crosstool. {@code
* linker_flag}s coming from linking_mode_flags and compilation_mode_flags are not included. If
* you need all possible linker flags, use {@link #configureAllLegacyLinkOptions(CompilationMode,
* LinkingMode)}.
*/
public ImmutableList<String> getLegacyLinkOptions() {
return toolchainInfo.getLegacyLinkOptions();
}
/**
* Return all flags coming from {@code compiler_flag} crosstool fields excluding flags coming from
* --copt options and copts attribute.
*/
public ImmutableList<String> getLegacyCompileOptions() {
ImmutableList.Builder<String> coptsBuilder =
ImmutableList.<String>builder()
.addAll(getToolchainCompilerFlags())
.addAll(getCFlagsByCompilationMode().get(cppConfiguration.getCompilationMode()));
if (cppConfiguration.isOmitfp()) {
coptsBuilder.add("-fomit-frame-pointer");
coptsBuilder.add("-fasynchronous-unwind-tables");
coptsBuilder.add("-DNO_FRAME_POINTER");
}
return coptsBuilder.build();
}
public ImmutableList<String> getLegacyCompileOptionsWithCopts() {
return ImmutableList.<String>builder()
.addAll(getLegacyCompileOptions())
.addAll(cppConfiguration.getCopts())
.build();
}
/** Return all possible {@code linker_flag} flags from the crosstool. */
ImmutableList<String> configureAllLegacyLinkOptions(
CompilationMode compilationMode, LinkingMode linkingMode) {
return toolchainInfo.configureAllLegacyLinkOptions(compilationMode, linkingMode);
}
/** Returns the GNU System Name */
@Override
public String getTargetGnuSystemName() {
return toolchainInfo == null ? null : toolchainInfo.getTargetGnuSystemName();
}
/** Returns the architecture component of the GNU System Name */
public String getGnuSystemArch() {
return toolchainInfo.getGnuSystemArch();
}
public final boolean isLLVMCompiler() {
return toolchainInfo.isLLVMCompiler();
}
public FdoMode getFdoMode() {
return fdoMode;
}
/**
* WARNING: This method is only added to allow incremental migration of existing users. Please do
* not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
*/
@Override
public ImmutableList<String> getCompilerOptions() throws EvalException {
cppConfiguration.checkForLegacyCompilationApiAvailability();
return getLegacyCompileOptionsWithCopts();
}
/**
* WARNING: This method is only added to allow incremental migration of existing users. Please do
* not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
*
* <p>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
* CcToolchainProvider#getLegacyCompileOptionsWithCopts()}.
*/
@Override
public ImmutableList<String> getCOptions() throws EvalException {
cppConfiguration.checkForLegacyCompilationApiAvailability();
return cppConfiguration.getCOptions();
}
/**
* WARNING: This method is only added to allow incremental migration of existing users. Please do
* not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
*
* <p>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}.
*/
@Override
@Deprecated
public ImmutableList<String> getCxxOptionsWithCopts() throws EvalException {
cppConfiguration.checkForLegacyCompilationApiAvailability();
return ImmutableList.<String>builder()
.addAll(getLegacyCxxOptions())
.addAll(cppConfiguration.getCxxopts())
.build();
}
public ImmutableList<String> getLegacyCxxOptions() {
return ImmutableList.<String>builder()
.addAll(getToolchainCxxFlags())
.addAll(getCxxFlagsByCompilationMode().get(cppConfiguration.getCompilationMode()))
.build();
}
/**
* WARNING: This method is only added to allow incremental migration of existing users. Please do
* not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
*
* <p>Returns the immutable list of linker options for fully statically linked outputs. Does not
* include command-line options passed via --linkopt or --linkopts.
*
* @param sharedLib true if the output is a shared lib, false if it's an executable
*/
@Override
@Deprecated
public ImmutableList<String> getFullyStaticLinkOptions(Boolean sharedLib) throws EvalException {
cppConfiguration.checkForLegacyLinkingApiAvailability();
if (!sharedLib) {
throw new EvalException(
Location.BUILTIN, "fully_static_link_options is deprecated, new uses are not allowed.");
}
return CppHelper.getFullyStaticLinkOptions(cppConfiguration, this, sharedLib);
}
/**
* WARNING: This method is only added to allow incremental migration of existing users. Please do
* not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
*
* <p>Returns the immutable list of linker options for mostly statically linked outputs. Does not
* include command-line options passed via --linkopt or --linkopts.
*
* @param sharedLib true if the output is a shared lib, false if it's an executable
*/
@Override
@Deprecated
public ImmutableList<String> getMostlyStaticLinkOptions(Boolean sharedLib) throws EvalException {
cppConfiguration.checkForLegacyLinkingApiAvailability();
return CppHelper.getMostlyStaticLinkOptions(
cppConfiguration, this, sharedLib, /* shouldStaticallyLinkCppRuntimes= */ true);
}
/**
* WARNING: This method is only added to allow incremental migration of existing users. Please do
* not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
*
* <p>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 sharedLib true if the output is a shared lib, false if it's an executable
*/
@Override
@Deprecated
public ImmutableList<String> getDynamicLinkOptions(Boolean sharedLib) throws EvalException {
cppConfiguration.checkForLegacyLinkingApiAvailability();
return CppHelper.getDynamicLinkOptions(cppConfiguration, this, sharedLib);
}
/**
* WARNING: This method is only added to allow incremental migration of existing users. Please do
* not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
*
* Returns the execution path to the linker binary to use for this build. Relative paths are
* relative to the execution root.
*/
@Override
public String getLdExecutableForSkylark() {
PathFragment ldExecutable = getToolPathFragment(CppConfiguration.Tool.LD);
return ldExecutable != null ? ldExecutable.getPathString() : "";
}
/**
* WARNING: This method is only added to allow incremental migration of existing users. Please do
* not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
*
* 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
public String getObjCopyExecutableForSkylark() {
PathFragment objCopyExecutable = getToolPathFragment(Tool.OBJCOPY);
return objCopyExecutable != null ? objCopyExecutable.getPathString() : "";
}
@Override
public String getCppExecutableForSkylark() {
PathFragment cppExecutable = getToolPathFragment(Tool.GCC);
return cppExecutable != null ? cppExecutable.getPathString() : "";
}
@Override
public String getCpreprocessorExecutableForSkylark() {
PathFragment cpreprocessorExecutable = getToolPathFragment(Tool.CPP);
return cpreprocessorExecutable != null ? cpreprocessorExecutable.getPathString() : "";
}
@Override
public String getNmExecutableForSkylark() {
PathFragment nmExecutable = getToolPathFragment(Tool.NM);
return nmExecutable != null ? nmExecutable.getPathString() : "";
}
@Override
public String getObjdumpExecutableForSkylark() {
PathFragment objdumpExecutable = getToolPathFragment(Tool.OBJDUMP);
return objdumpExecutable != null ? objdumpExecutable.getPathString() : "";
}
@Override
public String getArExecutableForSkylark() {
PathFragment arExecutable = getToolPathFragment(Tool.AR);
return arExecutable != null ? arExecutable.getPathString() : "";
}
@Override
public String getStripExecutableForSkylark() {
PathFragment stripExecutable = getToolPathFragment(Tool.STRIP);
return stripExecutable != null ? stripExecutable.getPathString() : "";
}
// Not all of CcToolchainProvider is exposed to Skylark, which makes implementing deep equality
// impossible: if Java-only parts are considered, the behavior is surprising in Skylark, if they
// are not, the behavior is surprising in Java. Thus, object identity it is.
@Override
public boolean equals(Object other) {
return other == this;
}
@Override
public int hashCode() {
return System.identityHashCode(this);
}
public boolean useLLVMCoverageMapFormat() {
return useLLVMCoverageMapFormat;
}
public boolean isCodeCoverageEnabled() {
return codeCoverageEnabled;
}
public boolean isHostConfiguration() {
return isHostConfiguration;
}
public boolean getForcePic() {
return forcePic;
}
public boolean getShouldStripBinaries() {
return shouldStripBinaries;
}
}