From 7855b888c4de7e09d4bad0d93ad56e6acc9939ce Mon Sep 17 00:00:00 2001 From: cpeyser Date: Wed, 27 Sep 2017 13:33:52 -0400 Subject: Add 'compiler' and 'libc' attributes to cc_toolchain. If platform/toolchain resolution is used, use these attribute values to choose a CToolchain from --crosstool_top instead of --compiler and --glibc. PiperOrigin-RevId: 170217186 --- .../devtools/build/lib/rules/cpp/CcToolchain.java | 45 +++++++++++++++ .../build/lib/rules/cpp/CcToolchainProvider.java | 10 ++++ .../build/lib/rules/cpp/CcToolchainRule.java | 8 ++- .../build/lib/rules/cpp/CppConfiguration.java | 15 +++++ .../lib/rules/cpp/CppConfigurationLoader.java | 8 ++- .../devtools/build/lib/rules/cpp/CppHelper.java | 33 ++++++----- .../cpp/CrosstoolConfigurationIdentifier.java | 3 +- .../rules/cpp/CrosstoolConfigurationLoader.java | 47 +++++++++++----- .../lib/packages/util/BazelMockCcSupport.java | 23 +++++--- .../build/lib/packages/util/Crosstool.java | 2 + .../lib/rules/cpp/CcToolchainProviderTest.java | 2 + .../lib/rules/cpp/CcToolchainSelectionTest.java | 64 +++++++++++++++++++++- 12 files changed, 221 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java index 11781594b5..15bc567281 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java @@ -28,6 +28,7 @@ import com.google.devtools.build.lib.analysis.LicensesProvider; import com.google.devtools.build.lib.analysis.LicensesProvider.TargetLicense; import com.google.devtools.build.lib.analysis.MakeVariableInfo; import com.google.devtools.build.lib.analysis.MiddlemanProvider; +import com.google.devtools.build.lib.analysis.PlatformConfiguration; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; @@ -48,12 +49,14 @@ import com.google.devtools.build.lib.packages.License; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.Builder; import com.google.devtools.build.lib.rules.cpp.FdoSupport.FdoException; +import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyKey; import java.io.IOException; @@ -369,9 +372,20 @@ public class CcToolchain implements RuleConfiguredTargetFactory { ruleContext.ruleError(e.getMessage()); } + PlatformConfiguration platformConfig = + Preconditions.checkNotNull(ruleContext.getFragment(PlatformConfiguration.class)); + + CToolchain toolchain = null; + if (platformConfig + .getEnabledToolchainTypes() + .contains(CppHelper.getToolchainTypeFromRuleClass(ruleContext))) { + toolchain = getToolchainFromAttributes(ruleContext, cppConfiguration); + } + CcToolchainProvider ccProvider = new CcToolchainProvider( cppConfiguration, + toolchain, crosstool, fullInputsForCrosstool(ruleContext, crosstoolMiddleman), compile, @@ -451,6 +465,37 @@ public class CcToolchain implements RuleConfiguredTargetFactory { return builder.build(); } + private CToolchain getToolchainFromAttributes( + RuleContext ruleContext, CppConfiguration cppConfiguration) throws RuleErrorException { + for (String requiredAttr : ImmutableList.of("cpu", "compiler", "libc")) { + if (ruleContext.attributes().get(requiredAttr, Type.STRING).isEmpty()) { + ruleContext.throwWithRuleError( + String.format( + "Using cc_toolchain target requires the attribute '%s' to be present.", + requiredAttr)); + } + } + + String cpu = ruleContext.attributes().get("cpu", Type.STRING); + String compiler = ruleContext.attributes().get("compiler", Type.STRING); + String libc = ruleContext.attributes().get("libc", Type.STRING); + CrosstoolConfigurationIdentifier config = + new CrosstoolConfigurationIdentifier(cpu, compiler, libc); + + try { + return CrosstoolConfigurationLoader.selectToolchain( + cppConfiguration.getCrosstoolFile().getProto(), + config, + cppConfiguration.getLipoMode(), + cppConfiguration.shouldConvertLipoToThinLto(), + cppConfiguration.getCpuTransformer()); + } catch (InvalidConfigurationException e) { + ruleContext.throwWithRuleError( + String.format("Error while using cc_toolchain: %s", e.getMessage())); + return null; + } + } + private ImmutableList getBuiltinIncludes(RuleContext ruleContext) { ImmutableList.Builder result = ImmutableList.builder(); for (Artifact artifact : inputsForLibc(ruleContext)) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java index 74aa13de0b..77eabde0cc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java @@ -29,6 +29,7 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain; import javax.annotation.Nullable; /** Information about a C++ compiler used by the cc_* rules. */ @@ -40,6 +41,7 @@ public final class CcToolchainProvider extends ToolchainInfo { /** An empty toolchain to be returned in the error case (instead of null). */ public static final CcToolchainProvider EMPTY_TOOLCHAIN_IS_ERROR = new CcToolchainProvider( + null, null, NestedSetBuilder.emptySet(Order.STABLE_ORDER), NestedSetBuilder.emptySet(Order.STABLE_ORDER), @@ -69,6 +71,7 @@ public final class CcToolchainProvider extends ToolchainInfo { null); @Nullable private final CppConfiguration cppConfiguration; + private final CToolchain toolchain; private final NestedSet crosstool; private final NestedSet crosstoolMiddleman; private final NestedSet compile; @@ -98,6 +101,7 @@ public final class CcToolchainProvider extends ToolchainInfo { public CcToolchainProvider( @Nullable CppConfiguration cppConfiguration, + CToolchain toolchain, NestedSet crosstool, NestedSet crosstoolMiddleman, NestedSet compile, @@ -126,6 +130,7 @@ public final class CcToolchainProvider extends ToolchainInfo { @Nullable PathFragment sysroot) { super(ImmutableMap.of(), Location.BUILTIN); this.cppConfiguration = cppConfiguration; + this.toolchain = toolchain; this.crosstool = Preconditions.checkNotNull(crosstool); this.crosstoolMiddleman = Preconditions.checkNotNull(crosstoolMiddleman); this.compile = Preconditions.checkNotNull(compile); @@ -163,6 +168,11 @@ public final class CcToolchainProvider extends ToolchainInfo { return builtInIncludeDirectories; } + /** Returns the {@link CToolchain} for this toolchain. */ + public CToolchain getToolchain() { + return toolchain; + } + /** * Returns all the files in Crosstool. Is not a middleman. */ diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java index 6672ca93bd..ab010e9396 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java @@ -23,6 +23,7 @@ import static com.google.devtools.build.lib.syntax.Type.STRING; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.MakeVariableInfo; +import com.google.devtools.build.lib.analysis.PlatformConfiguration; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.cmdline.Label; @@ -82,10 +83,12 @@ public final class CcToolchainRule implements RuleDefinition { } return builder .setUndocumented() - .requiresConfigurationFragments(CppConfiguration.class) + .requiresConfigurationFragments(CppConfiguration.class, PlatformConfiguration.class) .advertiseProvider(MakeVariableInfo.class) .add(attr("output_licenses", LICENSE)) .add(attr("cpu", STRING).mandatory()) + .add(attr("compiler", STRING)) + .add(attr("libc", STRING)) .add(attr("all_files", LABEL).legacyAllowAnyFileType().cfg(HOST).mandatory()) .add(attr("compiler_files", LABEL).legacyAllowAnyFileType().cfg(HOST).mandatory()) .add(attr("strip_files", LABEL).legacyAllowAnyFileType().cfg(HOST).mandatory()) @@ -108,6 +111,9 @@ public final class CcToolchainRule implements RuleDefinition { .cfg(HOST) .singleArtifact() .value(env.getToolsLabel("//tools/cpp:link_dynamic_library"))) + .add( + attr(CcToolchain.CC_TOOLCHAIN_TYPE_ATTRIBUTE_NAME, LABEL) + .value(CppRuleClasses.ccToolchainTypeAttribute(env))) .add( attr(":zipper", LABEL) .cfg(HOST) diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java index fa0f18f287..80824014ca 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.rules.cpp; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; import com.google.common.base.Verify; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; @@ -239,6 +240,7 @@ public class CppConfiguration extends BuildConfiguration.Fragment { private final String targetLibc; private final String targetOS; private final LipoMode lipoMode; + private final boolean convertLipoToThinLto; private final PathFragment crosstoolTopPathFragment; private final String abi; @@ -307,6 +309,7 @@ public class CppConfiguration extends BuildConfiguration.Fragment { private final ImmutableMap additionalMakeVariables; private final CppOptions cppOptions; + private final Function cpuTransformer; // The dynamic mode for linking. private final DynamicMode dynamicMode; @@ -334,6 +337,7 @@ public class CppConfiguration extends BuildConfiguration.Fragment { this.desiredCpu = Preconditions.checkNotNull(params.commonOptions.cpu); this.targetCpu = toolchain.getTargetCpu(); this.lipoMode = cppOptions.getLipoMode(); + this.convertLipoToThinLto = cppOptions.convertLipoToThinLto; this.targetSystemName = toolchain.getTargetSystemName(); this.targetLibc = toolchain.getTargetLibc(); this.targetOS = toolchain.getCcTargetOs(); @@ -345,6 +349,7 @@ public class CppConfiguration extends BuildConfiguration.Fragment { this.useLLVMCoverageMap = params.commonOptions.useLLVMCoverageMapFormat; this.lipoContextCollector = cppOptions.isLipoContextCollector(); this.crosstoolTopPathFragment = crosstoolTop.getPackageIdentifier().getPathUnderExecRoot(); + this.cpuTransformer = params.cpuTransformer; try { this.staticRuntimeLibsLabel = @@ -842,6 +847,11 @@ public class CppConfiguration extends BuildConfiguration.Fragment { return crosstoolFile; } + /** Returns the transformer that should be applied to cpu names in toolchain selection. */ + public Function getCpuTransformer() { + return cpuTransformer; + } + /** * Returns the path of the crosstool. */ @@ -1407,6 +1417,11 @@ public class CppConfiguration extends BuildConfiguration.Fragment { return cppOptions.getLipoMode(); } + /** Returns true if lipo should be converted to thinlto. */ + public boolean shouldConvertLipoToThinLto() { + return convertLipoToThinLto; + } + public boolean isFdo() { return cppOptions.isFdo(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java index 73f3b1b6ea..7ede7d4fdc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java @@ -92,6 +92,7 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory { protected final Label stlLabel; protected final Path fdoZip; protected final Label sysrootLabel; + protected final Function cpuTransformer; CppConfigurationParameters( CrosstoolConfig.CToolchain toolchain, @@ -102,7 +103,8 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory { Label crosstoolTop, Label ccToolchainLabel, Label stlLabel, - Label sysrootLabel) { + Label sysrootLabel, + Function cpuTransformer) { this.toolchain = toolchain; this.crosstoolFile = crosstoolFile; this.cacheKeySuffix = cacheKeySuffix; @@ -113,6 +115,7 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory { this.ccToolchainLabel = ccToolchainLabel; this.stlLabel = stlLabel; this.sysrootLabel = sysrootLabel; + this.cpuTransformer = cpuTransformer; } } @@ -234,7 +237,8 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory { crosstoolTopLabel, ccToolchainLabel, stlLabel, - sysrootLabel); + sysrootLabel, + cpuTransformer); } @Nullable diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java index 83649b6267..feaad45b72 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java @@ -318,14 +318,13 @@ public class CppHelper { } /** - * This almost trivial method looks up the given cc toolchain attribute on the rule context, makes - * sure that it refers to a rule that has a {@link CcToolchainProvider} - * (gives an error otherwise), and returns a reference to that {@link CcToolchainProvider}. - * The method only returns {@code null} if there is no such attribute - * (this is currently not an error). + * Makes sure that the given info collection has a {@link CcToolchainProvider} (gives an error + * otherwise), and returns a reference to that {@link CcToolchainProvider}. The method will only + * return {@code null}, if the toolchain attribute is undefined for the rule class. */ - @Nullable public static CcToolchainProvider getToolchain(RuleContext ruleContext, - String toolchainAttribute) { + @Nullable + public static CcToolchainProvider getToolchain( + RuleContext ruleContext, String toolchainAttribute) { if (!ruleContext.isAttrDefined(toolchainAttribute, LABEL)) { // TODO(bazel-team): Report an error or throw an exception in this case. return null; @@ -334,13 +333,8 @@ public class CppHelper { return getToolchain(ruleContext, dep); } - /** - * This almost trivial method makes sure that the given info collection has a {@link - * CcToolchainProvider} (gives an error otherwise), and returns a reference to that {@link - * CcToolchainProvider}. The method never returns {@code null}, even if there is no toolchain. - */ - public static CcToolchainProvider getToolchain(RuleContext ruleContext, - TransitiveInfoCollection dep) { + /** Returns the c++ toolchain type, or null if it is not specified on the rule class. */ + public static Label getToolchainTypeFromRuleClass(RuleContext ruleContext) { Label toolchainType; // TODO(b/65835260): Remove this conditional once j2objc can learn the toolchain type. if (ruleContext.attributes().has(CcToolchain.CC_TOOLCHAIN_TYPE_ATTRIBUTE_NAME)) { @@ -349,7 +343,18 @@ public class CppHelper { } else { toolchainType = null; } + return toolchainType; + } + + /** + * Makes sure that the given info collection has a {@link CcToolchainProvider} (gives an error + * otherwise), and returns a reference to that {@link CcToolchainProvider}. The method never + * returns {@code null}, even if there is no toolchain. + */ + public static CcToolchainProvider getToolchain( + RuleContext ruleContext, TransitiveInfoCollection dep) { + Label toolchainType = getToolchainTypeFromRuleClass(ruleContext); if (toolchainType != null && ruleContext .getFragment(PlatformConfiguration.class) diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationIdentifier.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationIdentifier.java index 390855b848..02028d10e2 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationIdentifier.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationIdentifier.java @@ -37,7 +37,8 @@ public final class CrosstoolConfigurationIdentifier implements CrosstoolConfigur /** The version of libc (e.g. glibc-2.11) associated with this crosstool configuration. */ private final String libc; - private CrosstoolConfigurationIdentifier(String cpu, String compiler, String libc) { + /** Creates a new {@link CrosstoolConfigurationIdentifier} with the given parameters. */ + CrosstoolConfigurationIdentifier(String cpu, String compiler, String libc) { this.cpu = cpu; this.compiler = compiler; this.libc = libc; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoader.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoader.java index 02962773fa..c712b186fd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoader.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoader.java @@ -279,23 +279,46 @@ public class CrosstoolConfigurationLoader { } /** - * Selects a crosstool toolchain corresponding to the given crosstool - * configuration options. If all of these options are null, it returns the default - * toolchain specified in the crosstool release. If only cpu is non-null, it - * returns the default toolchain for that cpu, as specified in the crosstool - * release. Otherwise, all values must be non-null, and this method - * returns the toolchain which matches all of the values. + * Selects a crosstool toolchain corresponding to the given crosstool configuration options. If + * all of these options are null, it returns the default toolchain specified in the crosstool + * release. If only cpu is non-null, it returns the default toolchain for that cpu, as specified + * in the crosstool release. Otherwise, all values must be non-null, and this method returns the + * toolchain which matches all of the values. * * @throws NullPointerException if {@code release} is null - * @throws InvalidConfigurationException if no matching toolchain can be found, or - * if the input parameters do not obey the constraints described above + * @throws InvalidConfigurationException if no matching toolchain can be found, or if the input + * parameters do not obey the constraints described above */ public static CrosstoolConfig.CToolchain selectToolchain( - CrosstoolConfig.CrosstoolRelease release, BuildOptions options, + CrosstoolConfig.CrosstoolRelease release, + BuildOptions options, Function cpuTransformer) - throws InvalidConfigurationException { + throws InvalidConfigurationException { CrosstoolConfigurationIdentifier config = CrosstoolConfigurationIdentifier.fromOptions(options); + CppOptions cppOptions = options.get(CppOptions.class); + return selectToolchain( + release, config, cppOptions.getLipoMode(), cppOptions.convertLipoToThinLto, cpuTransformer); + } + + /** + * Selects a crosstool toolchain corresponding to the given crosstool configuration options. If + * all of these options are null, it returns the default toolchain specified in the crosstool + * release. If only cpu is non-null, it returns the default toolchain for that cpu, as specified + * in the crosstool release. Otherwise, all values must be non-null, and this method returns the + * toolchain which matches all of the values. + * + * @throws NullPointerException if {@code release} is null + * @throws InvalidConfigurationException if no matching toolchain can be found, or if the input + * parameters do not obey the constraints described above + */ + public static CrosstoolConfig.CToolchain selectToolchain( + CrosstoolConfig.CrosstoolRelease release, + CrosstoolConfigurationIdentifier config, + LipoMode lipoMode, + boolean convertLipoToThinLto, + Function cpuTransformer) + throws InvalidConfigurationException { if ((config.getCompiler() != null) || (config.getLibc() != null)) { ArrayList candidateToolchains = new ArrayList<>(); for (CrosstoolConfig.CToolchain toolchain : release.getToolchainList()) { @@ -328,9 +351,7 @@ public class CrosstoolConfigurationLoader { // We use fake CPU values to allow cross-platform builds for other languages that use the // C++ toolchain. Translate to the actual target architecture. String desiredCpu = cpuTransformer.apply(config.getCpu()); - CppOptions cppOptions = options.get(CppOptions.class); - boolean needsLipo = - cppOptions.getLipoMode() != LipoMode.OFF && !cppOptions.convertLipoToThinLto; + boolean needsLipo = lipoMode != LipoMode.OFF && !convertLipoToThinLto; for (CrosstoolConfig.DefaultCpuToolchain selector : release.getDefaultToolchainList()) { if (needsLipo && !selector.getSupportsLipo()) { continue; diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockCcSupport.java b/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockCcSupport.java index 38266f3105..f1d52092a3 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockCcSupport.java +++ b/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockCcSupport.java @@ -93,48 +93,57 @@ public final class BazelMockCcSupport extends MockCcSupport { " 'ppc|compiler': ':cc-compiler-ppc',", " })", "cc_toolchain(name = 'cc-compiler-k8', all_files = ':empty', compiler_files = ':empty',", - " cpu = 'local', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ", + " cpu = 'k8', compiler = 'compiler', libc = 'local', dwp_files = ':empty',", + " dynamic_runtime_libs = [':empty'], ", " linker_files = ':empty',", " module_map = 'crosstool.cppmap', supports_header_parsing = 1,", " objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',", ")", "cc_toolchain(name = 'cc-compiler-ppc', all_files = ':empty', compiler_files = ':empty',", - " cpu = 'ppc', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ", + " cpu = 'ppc', compiler = 'compiler', libc = 'local', dwp_files = ':empty',", + " dynamic_runtime_libs = [':empty'], ", " linker_files = ':empty',", " module_map = 'crosstool.cppmap', supports_header_parsing = 1,", " objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',", ")", "cc_toolchain(name = 'cc-compiler-piii', all_files = ':all-files-piii',", " compiler_files = ':compiler-files-piii',", - " cpu = 'local', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ", + " cpu = 'piii', compiler = 'compiler', libc = 'local', dwp_files = ':empty',", + " dynamic_runtime_libs = [':empty'], ", " linker_files = ':empty',", " module_map = 'crosstool.cppmap', supports_header_parsing = 1,", " objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',", ")", "cc_toolchain(name = 'cc-compiler-darwin', all_files = ':empty', ", " compiler_files = ':empty',", - " cpu = 'local', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ", + " cpu = 'darwin', compiler = 'compiler', libc = 'macosx', dwp_files = ':empty',", + " dynamic_runtime_libs = [':empty'], ", " linker_files = ':empty',", " module_map = 'crosstool.cppmap', supports_header_parsing = 1,", " objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',", ")", "cc_toolchain(name = 'cc-compiler-ios_x86_64', all_files = ':empty', ", " compiler_files = ':empty',", - " cpu = 'local', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ", + " cpu = 'ios_x86_64', compiler = 'compiler', libc = 'local', dwp_files = ':empty',", + " dynamic_runtime_libs = [':empty'], ", " linker_files = ':empty',", " module_map = 'crosstool.cppmap', supports_header_parsing = 1,", " objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',", ")", "cc_toolchain(name = 'cc-compiler-armeabi-v7a', all_files = ':empty', ", " compiler_files = ':empty',", - " cpu = 'local', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ", + " cpu = 'armeabi-v7a', compiler = 'compiler', libc = 'armeabi-v7a', ", + " dwp_files = ':empty',", + " dynamic_runtime_libs = [':empty'], ", " linker_files = ':empty',", " module_map = 'crosstool.cppmap', supports_header_parsing = 1,", " objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',", ")", "cc_toolchain(name = 'cc-compiler-x64_windows', all_files = ':empty', ", " compiler_files = ':empty',", - " cpu = 'local', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ", + " cpu = 'x64_windows', compiler = 'windows_msys64', libc = 'local', ", + " dwp_files = ':empty',", + " dynamic_runtime_libs = [':empty'], ", " linker_files = ':empty',", " module_map = 'crosstool.cppmap', supports_header_parsing = 1,", " objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',", diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/Crosstool.java b/src/test/java/com/google/devtools/build/lib/packages/util/Crosstool.java index 3642fda958..1f51043e49 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/util/Crosstool.java +++ b/src/test/java/com/google/devtools/build/lib/packages/util/Crosstool.java @@ -139,6 +139,8 @@ final class Crosstool { " output_licenses = ['unencumbered'],", addModuleMap ? " module_map = 'crosstool.cppmap'," : "", " cpu = '" + arch + "',", + " compiler = 'gcc-4.4.0',", + " libc = 'glibc-2.3.6-grte',", " compiler_files = 'compile-" + arch + "',", " dwp_files = 'dwp-" + arch + "',", " linker_files = 'link-" + arch + "',", diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderTest.java index bc93ba92b2..89d0cbc8f0 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderTest.java @@ -36,6 +36,7 @@ public class CcToolchainProviderTest { public void equalityIsObjectIdentity() throws Exception { CcToolchainProvider a = new CcToolchainProvider( + null, null, NestedSetBuilder.emptySet(Order.STABLE_ORDER), NestedSetBuilder.emptySet(Order.STABLE_ORDER), @@ -66,6 +67,7 @@ public class CcToolchainProviderTest { CcToolchainProvider b = new CcToolchainProvider( + null, null, NestedSetBuilder.emptySet(Order.STABLE_ORDER), NestedSetBuilder.emptySet(Order.STABLE_ORDER), diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSelectionTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSelectionTest.java index 588ff24842..8bb82384b8 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSelectionTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSelectionTest.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.analysis.util.ScratchAttributeWriter; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.util.MockPlatformSupport; +import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.testutil.TestConstants; import java.util.List; import org.junit.Before; @@ -51,7 +52,7 @@ public class CcToolchainSelectionTest extends BuildViewTestCase { return compilationSteps.get(0); } - private static String CPP_TOOLCHAIN_TYPE = + private static final String CPP_TOOLCHAIN_TYPE = TestConstants.TOOLS_REPOSITORY + "//tools/cpp:toolchain_category"; @Test @@ -104,4 +105,65 @@ public class CcToolchainSelectionTest extends BuildViewTestCase { providers.getForToolchainType(Label.parseAbsolute(CPP_TOOLCHAIN_TYPE)); assertThat(toolchain.getKeys()).isEmpty(); } + + @Test + public void testCToolchainSelectionFromCcToolchainAttrs() throws Exception { + useConfiguration( + "--enabled_toolchain_types=" + CPP_TOOLCHAIN_TYPE, + "--experimental_platforms=//mock_platform:mock-piii-platform", + "--extra_toolchains=//mock_platform:toolchain_cc-compiler-piii"); + ConfiguredTarget target = + ScratchAttributeWriter.fromLabelString(this, "cc_library", "//lib") + .setList("srcs", "a.cc") + .write(); + ResolvedToolchainProviders providers = + (ResolvedToolchainProviders) + getRuleContext(target).getToolchainContext().getResolvedToolchainProviders(); + CcToolchainProvider toolchain = + (CcToolchainProvider) + providers.getForToolchainType(Label.parseAbsolute(CPP_TOOLCHAIN_TYPE)); + assertThat(toolchain.getToolchain().getTargetCpu()).isEqualTo("piii"); + } + + @Test + public void testErrorForIncompleteCcToolchain() throws Exception { + mockToolsConfig.create( + "incomplete_toolchain/BUILD", + "toolchain(", + " name = 'incomplete_toolchain_cc-compiler-piii',", + " toolchain_type = '" + CPP_TOOLCHAIN_TYPE + "',", + " toolchain = ':incomplete_cc-compiler-piii',", + " target_compatible_with = ['//mock_platform:mock_value']", + ")", + "cc_toolchain(", + " name = 'incomplete_cc-compiler-piii',", + " cpu = 'piii',", + " compiler_files = 'compile-piii',", + " dwp_files = 'dwp-piii',", + " linker_files = 'link-piii',", + " strip_files = ':dummy_filegroup',", + " objcopy_files = 'objcopy-piii',", + " all_files = ':dummy_filegroup',", + " static_runtime_libs = ['static-runtime-libs-piii'],", + " dynamic_runtime_libs = ['dynamic-runtime-libs-piii'],", + ")", + "filegroup(name = 'dummy_filegroup')"); + + useConfiguration( + "--enabled_toolchain_types=" + CPP_TOOLCHAIN_TYPE, + "--experimental_platforms=//mock_platform:mock-piii-platform", + "--extra_toolchains=//incomplete_toolchain:incomplete_toolchain_cc-compiler-piii"); + + AssertionError thrown = + MoreAsserts.expectThrows( + AssertionError.class, + () -> + ScratchAttributeWriter.fromLabelString(this, "cc_library", "//lib") + .setList("srcs", "a.cc") + .write()); + + assertThat(thrown) + .hasMessageThat() + .contains("Using cc_toolchain target requires the attribute 'compiler' to be present"); + } } -- cgit v1.2.3