aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
diff options
context:
space:
mode:
authorGravatar John Cater <jcater@google.com>2018-03-02 07:27:01 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-03-02 07:28:59 -0800
commit52ec7fb1c22afea1a172a5720ddca44d88bbdee8 (patch)
treed57046944b71e72504459b3ad84d852e6814867e /src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
parent3b446a28d210c83932e47df2452b4b6224a1834b (diff)
Allow cc_toolchain to have inline proto toolchain data, instead of using crosstool top.
Change-Id: I531034b0c991d18b05818db4b40cbd739535b565 PiperOrigin-RevId: 187617580
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java87
1 files changed, 62 insertions, 25 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 62cd8cc307..11628db62f 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
@@ -65,10 +65,13 @@ 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 com.google.protobuf.TextFormat;
+import com.google.protobuf.TextFormat.ParseException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import javax.annotation.Nullable;
/**
* Implementation for the cc_toolchain rule.
@@ -312,30 +315,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
CppConfiguration cppConfiguration =
Preconditions.checkNotNull(ruleContext.getFragment(CppConfiguration.class));
- PlatformConfiguration platformConfig =
- Preconditions.checkNotNull(ruleContext.getFragment(PlatformConfiguration.class));
-
- CToolchain toolchain = null;
- if (platformConfig
- .getEnabledToolchainTypes()
- .contains(CppHelper.getToolchainTypeFromRuleClass(ruleContext))) {
- toolchain = getToolchainFromAttributes(ruleContext, cppConfiguration);
- }
-
- CppToolchainInfo toolchainInfo = null;
- if (toolchain != null) {
- try {
- toolchainInfo =
- CppToolchainInfo.create(
- toolchain,
- cppConfiguration.getCrosstoolTopPathFragment(),
- cppConfiguration.getCcToolchainRuleLabel());
- } catch (InvalidConfigurationException e) {
- ruleContext.throwWithRuleError(e.getMessage());
- }
- } else {
- toolchainInfo = cppConfiguration.getCppToolchainInfo();
- }
+ CppToolchainInfo toolchainInfo = getCppToolchainInfo(ruleContext, cppConfiguration);
Path fdoZip = null;
if (ruleContext.getConfiguration().getCompilationMode() == CompilationMode.OPT) {
@@ -610,6 +590,47 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
return builder.build();
}
+ /** Finds an appropriate {@link CppToolchainInfo} for this target. */
+ private CppToolchainInfo getCppToolchainInfo(
+ RuleContext ruleContext, CppConfiguration cppConfiguration) throws RuleErrorException {
+
+ // Attempt to find a toolchain based on the target attributes, not the configuration.
+ CToolchain toolchain = getToolchainFromAttributes(ruleContext, cppConfiguration);
+
+ if (toolchain == null) {
+ // Fall back to the toolchain info in the current configuration.
+ return cppConfiguration.getCppToolchainInfo();
+ }
+
+ // If we found a toolchain, use it.
+ try {
+ return CppToolchainInfo.create(
+ toolchain,
+ cppConfiguration.getCrosstoolTopPathFragment(),
+ cppConfiguration.getCcToolchainRuleLabel());
+ } catch (InvalidConfigurationException e) {
+ throw ruleContext.throwWithRuleError(e.getMessage());
+ }
+ }
+
+ @Nullable
+ private CToolchain parseToolchainFromAttributes(RuleContext ruleContext)
+ throws RuleErrorException {
+ if (ruleContext.attributes().get("proto", Type.STRING).isEmpty()) {
+ return null;
+ }
+
+ String data = ruleContext.attributes().get("proto", Type.STRING);
+
+ CToolchain.Builder builder = CToolchain.newBuilder();
+ try {
+ TextFormat.merge(data, builder);
+ return builder.build();
+ } catch (ParseException e) {
+ throw ruleContext.throwWithAttributeError("proto", "Could not parse CToolchain data");
+ }
+ }
+
private void reportInvalidOptions(RuleContext ruleContext, CppToolchainInfo toolchain) {
CppOptions options = ruleContext.getConfiguration().getOptions().get(CppOptions.class);
CppConfiguration config = ruleContext.getFragment(CppConfiguration.class);
@@ -647,14 +668,30 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
.build();
}
+ @Nullable
private CToolchain getToolchainFromAttributes(
RuleContext ruleContext, CppConfiguration cppConfiguration) throws RuleErrorException {
+ PlatformConfiguration platformConfig =
+ Preconditions.checkNotNull(ruleContext.getFragment(PlatformConfiguration.class));
+
+ if (!platformConfig
+ .getEnabledToolchainTypes()
+ .contains(CppHelper.getToolchainTypeFromRuleClass(ruleContext))) {
+ return null;
+ }
+
+ // Is there a toolchain proto available on the target directly?
+ CToolchain toolchain = parseToolchainFromAttributes(ruleContext);
+ if (toolchain != null) {
+ return toolchain;
+ }
+
+ // Use the attributes to find the proper toolchain from the CROSSTOOL.
if (ruleContext.attributes().get("cpu", Type.STRING).isEmpty()) {
ruleContext.throwWithRuleError("Using cc_toolchain target requires the attribute 'cpu' "
+ "to be present");
}
-
String cpu = ruleContext.attributes().get("cpu", Type.STRING);
String compiler = ruleContext.attributes().get("compiler", Type.STRING);
if (compiler.isEmpty()) {