diff options
author | John Cater <jcater@google.com> | 2018-03-02 07:27:01 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-03-02 07:28:59 -0800 |
commit | 52ec7fb1c22afea1a172a5720ddca44d88bbdee8 (patch) | |
tree | d57046944b71e72504459b3ad84d852e6814867e /src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java | |
parent | 3b446a28d210c83932e47df2452b4b6224a1834b (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.java | 87 |
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()) { |