aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules
diff options
context:
space:
mode:
authorGravatar cpeyser <cpeyser@google.com>2017-09-27 13:33:52 -0400
committerGravatar John Cater <jcater@google.com>2017-09-28 08:54:46 -0400
commit7855b888c4de7e09d4bad0d93ad56e6acc9939ce (patch)
tree43afc8a65b381a2b5a0cdcba00e0d8e9482b904c /src/main/java/com/google/devtools/build/lib/rules
parent272561c6fda79926040cfaa292cb0b4e85fdb84b (diff)
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
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java45
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java33
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationIdentifier.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoader.java47
8 files changed, 138 insertions, 31 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<Artifact> getBuiltinIncludes(RuleContext ruleContext) {
ImmutableList.Builder<Artifact> 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 <code>cc_*</code> rules. */
@@ -41,6 +42,7 @@ public final class CcToolchainProvider extends ToolchainInfo {
public static final CcToolchainProvider EMPTY_TOOLCHAIN_IS_ERROR =
new CcToolchainProvider(
null,
+ null,
NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
NestedSetBuilder.<Artifact>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<Artifact> crosstool;
private final NestedSet<Artifact> crosstoolMiddleman;
private final NestedSet<Artifact> compile;
@@ -98,6 +101,7 @@ public final class CcToolchainProvider extends ToolchainInfo {
public CcToolchainProvider(
@Nullable CppConfiguration cppConfiguration,
+ CToolchain toolchain,
NestedSet<Artifact> crosstool,
NestedSet<Artifact> crosstoolMiddleman,
NestedSet<Artifact> 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())
@@ -109,6 +112,9 @@ public final class CcToolchainRule implements RuleDefinition {
.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)
.singleArtifact()
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<String, String> additionalMakeVariables;
private final CppOptions cppOptions;
+ private final Function<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> cpuTransformer)
+ throws InvalidConfigurationException {
if ((config.getCompiler() != null) || (config.getLibc() != null)) {
ArrayList<CrosstoolConfig.CToolchain> 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;