diff options
author | 2018-05-30 11:12:00 -0700 | |
---|---|---|
committer | 2018-05-30 11:13:39 -0700 | |
commit | a14d421edc898f50e3d269a74c5844c587d56abe (patch) | |
tree | 233ece2adde8f1836296560378cf4adfbcecafc5 | |
parent | 252e3b817e444ddfe264e8cbc5f1203023e61926 (diff) |
Modify cc_toolchain_suite rule to allow selection of cc_toolchain label without reading the CROSSTOOL file.
As we want to reroute selecting the toolchain from CROSSTOOL through cc_toolchain, cc_toolchain_suite should have all the necesarry information for obtaining the cc_toolchain label without accessing the CROSSTOOL file.
In order to do that, besides the existing <toolchain.targetCpu>|<toolchain.compiler>, we add <cpu> type of key in 'toolchains' attribute of cc_toolchain_suite.
Now the selection of cc_toolchain label goes as follows:
1. Return toolchains[<cpu>|<compiler> if it exists
2. Return toolchains[<cpu>] if it exists
3. Fall back to the previous state: return toolchains[<toolchain.targetCpu>|<toolchain.compiler>]
RELNOTES: None.
PiperOrigin-RevId: 198588849
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java | 28 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuiteTest.java | 139 |
2 files changed, 161 insertions, 6 deletions
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 e91ad2214d..e20e3a0d4c 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 @@ -14,10 +14,12 @@ package com.google.devtools.build.lib.rules.cpp; + import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.analysis.RedirectChaser; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Options; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment; import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory; @@ -34,6 +36,7 @@ import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig; import com.google.devtools.common.options.OptionsParsingException; +import java.util.Map; import javax.annotation.Nullable; /** @@ -175,13 +178,26 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory { if (crosstoolTop instanceof Rule && ((Rule) crosstoolTop).getRuleClass().equals("cc_toolchain_suite")) { Rule ccToolchainSuite = (Rule) crosstoolTop; - ccToolchainLabel = NonconfigurableAttributeMapper.of(ccToolchainSuite) - .get("toolchains", BuildType.LABEL_DICT_UNARY) - .get(toolchain.getTargetCpu() + "|" + toolchain.getCompiler()); + + String desiredCpu = cpuTransformer.getTransformer().apply(options.get(Options.class).cpu); + String key = + desiredCpu + (cppOptions.cppCompiler == null ? "" : ("|" + cppOptions.cppCompiler)); + Map<String, Label> toolchains = + NonconfigurableAttributeMapper.of(ccToolchainSuite) + .get("toolchains", BuildType.LABEL_DICT_UNARY); + ccToolchainLabel = toolchains.get(key); if (ccToolchainLabel == null) { - throw new InvalidConfigurationException(String.format( - "cc_toolchain_suite '%s' does not contain a toolchain for CPU '%s' and compiler '%s'", - crosstoolTopLabel, toolchain.getTargetCpu(), toolchain.getCompiler())); + ccToolchainLabel = toolchains.get(toolchain.getTargetCpu() + "|" + toolchain.getCompiler()); + } + if (ccToolchainLabel == null) { + String errorMessage = + String.format( + "cc_toolchain_suite '%s' does not contain a toolchain for CPU '%s'", + crosstoolTopLabel, toolchain.getTargetCpu()); + if (cppOptions.cppCompiler != null) { + errorMessage = errorMessage + " and compiler " + cppOptions.cppCompiler; + } + throw new InvalidConfigurationException(errorMessage); } } else { throw new InvalidConfigurationException(String.format( diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuiteTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuiteTest.java index db890c891e..f6925f2d85 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuiteTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuiteTest.java @@ -15,10 +15,13 @@ package com.google.devtools.build.lib.rules.cpp; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import org.junit.Test; @@ -241,4 +244,140 @@ public class CcToolchainSuiteTest extends BuildViewTestCase { assertThat(ActionsTestUtil.baseArtifactNames(suiteFiles)) .containsAllOf("k8-marker", "darwin-marker", "windows-marker", "linux-marker"); } + + @Test + public void testCcToolchainLabelFromAttributes() throws Exception { + scratch.file( + "cc/BUILD", + "filegroup(name='empty')", + "filegroup(name='everything')", + "TOOLCHAIN_NAMES = [", + " 'darwin-from-crosstool',", + " 'windows-from-crosstool',", + " 'k8-compiler',", + " 'k8-default-from-cpu',", + " 'ppc-compiler',", + " 'ppc-default-from-cpu']", + "[cc_toolchain(", + " name = NAME,", + " cpu = 'banana',", + " all_files = ':empty',", + " ar_files = ':empty',", + " as_files = ':empty',", + " compiler_files = ':empty',", + " dwp_files = ':empty',", + " linker_files = ':empty',", + " strip_files = ':empty',", + " objcopy_files = ':empty',", + " dynamic_runtime_libs = [':empty'],", + " static_runtime_libs = [':empty'],", + ") for NAME in TOOLCHAIN_NAMES]", + "cc_toolchain_suite(", + " name = 'suite',", + " toolchains = {", + " 'k8|compiler': ':k8-compiler',", + " 'ppc': ':invalid-label',", + " 'ppc|compiler': ':ppc-compiler',", + " 'k8': ':k8-default-from-cpu',", + " 'x64_windows' : ':windows-from-crosstool',", + " 'darwin' : ':darwin-from-crosstool',", + " 'x64_windows|compiler' : ':windows-from-crosstool',", + " 'darwin|compiler' : ':darwin-from-crosstool',", + " },", + " proto = \"\"\"", + "major_version: 'v1'", + "minor_version: '0'", + "default_target_cpu: 'k8'", + "default_toolchain {", + " cpu: 'k8'", + " toolchain_identifier: 'k8-from-crosstool'", + "}", + "default_toolchain {", + " cpu: 'ppc'", + " toolchain_identifier: 'ppc-from-crosstool'", + "}", + "default_toolchain {", + " cpu: 'darwin'", + " toolchain_identifier: 'darwin-from-crosstool'", + "}", + "default_toolchain {", + " cpu: 'x64_windows'", + " toolchain_identifier: 'windows-from-crosstool'", + "}", + "toolchain {", + " compiler: 'compiler'", + " target_cpu: 'k8'", + " toolchain_identifier: 'k8-from-crosstool'", + " host_system_name: 'linux'", + " target_system_name: 'linux'", + " abi_version: 'cpu-abi'", + " abi_libc_version: ''", + " target_libc: 'local'", + " builtin_sysroot: 'sysroot'", + " default_grte_top: '//cc:grtetop'", + "}", + "toolchain {", + " compiler: 'compiler'", + " target_cpu: 'ppc'", + " toolchain_identifier: 'ppc-from-crosstool'", + " host_system_name: 'linux'", + " target_system_name: 'linux'", + " abi_version: 'cpu-abi'", + " abi_libc_version: ''", + " target_libc: 'local'", + " builtin_sysroot: 'sysroot'", + " default_grte_top: '//cc:grtetop'", + "}", + "toolchain {", + " compiler: 'compiler'", + " target_cpu: 'darwin'", + " toolchain_identifier: 'darwin-from-crosstool'", + " host_system_name: 'linux'", + " target_system_name: 'linux'", + " abi_version: ''", + " abi_libc_version: ''", + " target_libc: ''", + " builtin_sysroot: 'sysroot'", + " default_grte_top: '//cc:grtetop'", + "}", + "toolchain {", + " compiler: 'compiler'", + " target_cpu: 'x64_windows'", + " toolchain_identifier: 'windows-from-crosstool'", + " host_system_name: 'windows'", + " target_system_name: 'windows'", + " abi_version: ''", + " abi_libc_version: ''", + " target_libc: ''", + " builtin_sysroot: 'sysroot'", + " default_grte_top: '//cc:grtetop'", + "}", + "\"\"\"", + ")"); + + scratch.file("a/BUILD", "cc_binary(name='b', srcs=['b.cc'])"); + + useConfiguration("--crosstool_top=//cc:suite", "--cpu=k8"); + ConfiguredTarget c = getConfiguredTarget("//a:b"); + CppConfiguration config = getConfiguration(c).getFragment(CppConfiguration.class); + assertThat(config.getCcToolchainRuleLabel().toString()).isEqualTo("//cc:k8-default-from-cpu"); + + useConfiguration("--crosstool_top=//cc:suite", "--compiler=compiler", "--cpu=ppc"); + config = getConfiguration(getConfiguredTarget("//a:b")).getFragment(CppConfiguration.class); + assertThat(config.getCcToolchainRuleLabel().toString()).isEqualTo("//cc:ppc-compiler"); + + useConfiguration("--crosstool_top=//cc:suite", "--compiler=compiler", "--cpu=k8"); + config = getConfiguration(getConfiguredTarget("//a:b")).getFragment(CppConfiguration.class); + assertThat(config.getCcToolchainRuleLabel().toString()).isEqualTo("//cc:k8-compiler"); + + try { + useConfiguration("--crosstool_top=//cc:suite", "--cpu=ppc"); + getConfiguration(getConfiguredTarget("//a:b")).getFragment(CppConfiguration.class); + fail("expected failure because 'ppc' entry points to an invalid label"); + } catch (InvalidConfigurationException e) { + assertThat(e) + .hasMessageThat() + .contains("The label '//cc:invalid-label' is not a cc_toolchain rule"); + } + } } |