// 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.FdoSupport.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 cc_* 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), /* 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, /* useLLVMCoverageMapFormat= */ false, /* codeCoverageEnabled= */ false, /* isHostConfiguration= */ false); @Nullable private final CppConfiguration cppConfiguration; private final CppToolchainInfo toolchainInfo; private final PathFragment crosstoolTopPathFragment; private final NestedSet crosstool; private final NestedSet crosstoolMiddleman; private final NestedSet compile; private final NestedSet strip; private final NestedSet objCopy; private final NestedSet as; private final NestedSet ar; private final NestedSet link; private final Artifact interfaceSoBuilder; private final NestedSet dwp; private final NestedSet coverage; private final NestedSet libcLink; private final NestedSet staticRuntimeLinkInputs; @Nullable private final Artifact staticRuntimeLinkMiddleman; private final NestedSet 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 builtinIncludeFiles; private final NestedSet> coverageEnvironment; @Nullable private final Artifact linkDynamicLibraryTool; private final ImmutableList 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; public CcToolchainProvider( ImmutableMap values, @Nullable CppConfiguration cppConfiguration, CppToolchainInfo toolchainInfo, PathFragment crosstoolTopPathFragment, NestedSet crosstool, NestedSet crosstoolMiddleman, NestedSet compile, NestedSet strip, NestedSet objCopy, NestedSet as, NestedSet ar, NestedSet link, Artifact interfaceSoBuilder, NestedSet dwp, NestedSet coverage, NestedSet libcLink, NestedSet staticRuntimeLinkInputs, @Nullable Artifact staticRuntimeLinkMiddleman, NestedSet dynamicRuntimeLinkInputs, @Nullable Artifact dynamicRuntimeLinkMiddleman, PathFragment dynamicRuntimeSolibDir, CcCompilationContext ccCompilationContext, boolean supportsParamFiles, boolean supportsHeaderParsing, CcToolchainVariables buildVariables, ImmutableList builtinIncludeFiles, NestedSet> coverageEnvironment, Artifact linkDynamicLibraryTool, ImmutableList builtInIncludeDirectories, @Nullable PathFragment sysroot, FdoMode fdoMode, 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.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.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 getCppBuildVariables( Function getToolPathFragment, String targetLibc, String compiler, String targetCpu, PathFragment crosstoolTopPathFragment, String abiGlibcVersion, String abi, Map additionalMakeVariables) { ImmutableMap.Builder 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 */ public boolean usePicForDynamicLibraries() { return getCppConfiguration().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. * *

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 globalMakeEnvBuilder) { globalMakeEnvBuilder.putAll( getCppBuildVariables( this::getToolPathFragment, getTargetLibc(), getCompiler(), getTargetCpu(), crosstoolTopPathFragment, getAbiGlibcVersion(), getAbi(), getAdditionalMakeVariables())); } @Override public ImmutableList getBuiltInIncludeDirectoriesAsStrings() { return builtInIncludeDirectories .stream() .map(PathFragment::getSafePathString) .collect(ImmutableList.toImmutableList()); } public ImmutableList 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 getCrosstool() { return crosstool; } /** * Returns a middleman for all the files in Crosstool. */ public NestedSet getCrosstoolMiddleman() { return crosstoolMiddleman; } /** * Returns the files necessary for compilation. */ public NestedSet getCompile() { return compile; } /** * Returns the files necessary for a 'strip' invocation. */ public NestedSet getStrip() { return strip; } /** * Returns the files necessary for an 'objcopy' invocation. */ public NestedSet 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 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 getAr() { return ar; } /** * Returns the files necessary for linking, including the files needed for libc. */ public NestedSet getLink() { return link; } public NestedSet getDwp() { return dwp; } /** * Returns the files necessary for capturing code coverage. */ public NestedSet getCoverage() { return coverage; } public NestedSet 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 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 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 null. */ 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_}. */ 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. * *

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 getBuiltinIncludeFiles() { return builtinIncludeFiles; } /** * Returns the environment variables that need to be added to tests that collect code coverage. */ public NestedSet> 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. * *

The returned map must contain an entry for {@code STACK_FRAME_UNLIMITED}, though the entry * may be an empty string. */ public ImmutableMap getAdditionalMakeVariables() { return toolchainInfo.getAdditionalMakeVariables(); } /** * 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 getUnfilteredCompilerOptionsWithSysroot( Iterable featuresNotUsedAnymore) throws EvalException { cppConfiguration.checkForLegacyCompilationApiAvailability(); return toolchainInfo.getUnfilteredCompilerOptions(sysroot); } public ImmutableList getUnfilteredCompilerOptions() { return toolchainInfo.getUnfilteredCompilerOptions(/* sysroot= */ null); } /** * Unused, for compatibility with things internal to Google. * *

Deprecated: Use platforms. */ @Deprecated public String getTargetOS() { return toolchainInfo.getTargetOS(); } @Override public ImmutableList getLinkOptionsWithSysroot() throws EvalException { if (cppConfiguration == null) { return ImmutableList.of(); } cppConfiguration.checkForLegacyLinkingApiAvailability(); return cppConfiguration.getLinkOptionsDoNotUse(sysroot); } public ImmutableList 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 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 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 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 getSharedLibraryLinkOptions(ImmutableList flags) { return toolchainInfo.getSharedLibraryLinkOptions(flags); } /** Returns compiler flags arising from the {@link CToolchain}. */ ImmutableList getToolchainCompilerFlags() { return toolchainInfo.getCompilerFlags(); } /** Returns additional compiler flags for C++ arising from the {@link CToolchain} */ ImmutableList getToolchainCxxFlags() { return toolchainInfo.getCxxFlags(); } /** * Returns compiler flags arising from the {@link CToolchain} for C compilation by compilation * mode. */ ImmutableListMultimap getCFlagsByCompilationMode() { return toolchainInfo.getCFlagsByCompilationMode(); } /** * Returns compiler flags arising from the {@link CToolchain} for C++ compilation by compilation * mode. */ ImmutableListMultimap getCxxFlagsByCompilationMode() { return toolchainInfo.getCxxFlagsByCompilationMode(); } /** Returns linker flags for fully statically linked outputs. */ ImmutableList getLegacyFullyStaticLinkFlags(CompilationMode compilationMode) { return configureAllLegacyLinkOptions(compilationMode, LinkingMode.LEGACY_FULLY_STATIC); } /** Returns linker flags for mostly static linked outputs. */ ImmutableList getLegacyMostlyStaticLinkFlags(CompilationMode compilationMode) { return configureAllLegacyLinkOptions(compilationMode, LinkingMode.STATIC); } /** Returns linker flags for mostly static shared linked outputs. */ ImmutableList 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 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 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 getLegacyCompileOptions() { ImmutableList.Builder coptsBuilder = ImmutableList.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 getLegacyCompileOptionsWithCopts() { return ImmutableList.builder() .addAll(getLegacyCompileOptions()) .addAll(cppConfiguration.getCopts()) .build(); } /** Return all possible {@code linker_flag} flags from the crosstool. */ ImmutableList 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 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. * *

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 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. * *

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 getCxxOptionsWithCopts() throws EvalException { cppConfiguration.checkForLegacyCompilationApiAvailability(); return ImmutableList.builder() .addAll(getLegacyCxxOptions()) .addAll(cppConfiguration.getCxxopts()) .build(); } public ImmutableList getLegacyCxxOptions() { return ImmutableList.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. * *

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 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. * *

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 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. * *

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 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; } }