Skip to content

Commit 4dca905

Browse files
ckolli5cpsauer
andauthored
Improve error message for unresolved toolchains (bazelbuild#15451)
Closes bazelbuild#15135. PiperOrigin-RevId: 447028054 Co-authored-by: Christopher Peterson Sauer <[email protected]>
1 parent f69e198 commit 4dca905

File tree

3 files changed

+205
-22
lines changed

3 files changed

+205
-22
lines changed

src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.google.common.collect.ImmutableMap;
2525
import com.google.common.collect.ImmutableSet;
2626
import com.google.common.collect.ImmutableSetMultimap;
27-
import com.google.common.collect.Iterables;
2827
import com.google.common.collect.Table;
2928
import com.google.devtools.build.lib.analysis.PlatformConfiguration;
3029
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -578,20 +577,14 @@ protected Code getDetailedCode() {
578577
}
579578

580579
private static String getMessage(List<Label> missingToolchainTypes) {
581-
if (missingToolchainTypes.size() == 1
582-
&& Iterables.getOnlyElement(missingToolchainTypes)
583-
.toString()
584-
.equals("@bazel_tools//tools/cpp:toolchain_type")) {
585-
return "No matching toolchains found for types @bazel_tools//tools/cpp:toolchain_type. "
586-
+ "Maybe --incompatible_use_cc_configure_from_rules_cc has been flipped and there "
587-
+ "is no default C++ toolchain added in the WORKSPACE file? See "
588-
+ "https://github.com/bazelbuild/bazel/issues/10134 for details and migration "
589-
+ "instructions.";
590-
}
591-
580+
ImmutableList<String> labelStrings =
581+
missingToolchainTypes.stream().map(Label::toString).collect(toImmutableList());
592582
return String.format(
593-
"no matching toolchains found for types %s",
594-
missingToolchainTypes.stream().map(Label::toString).collect(joining(", ")));
583+
"No matching toolchains found for types %s."
584+
+ "\nTo debug, rerun with --toolchain_resolution_debug='%s'"
585+
+ "\nIf platforms or toolchains are a new concept for you, we'd encourage reading "
586+
+ "https://bazel.build/concepts/platforms-intro.",
587+
String.join(", ", labelStrings), String.join("|", labelStrings));
595588
}
596589
}
597590

src/test/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunctionTest.java

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,196 @@ public void resolve() throws Exception {
8585
assertThat(unloadedToolchainContext).hasTargetPlatform("//platforms:linux");
8686
}
8787

88+
// TODO(katre): Add further tests for optional/mandatory/mixed toolchains.
89+
90+
@Test
91+
public void resolve_optional() throws Exception {
92+
// This should select platform mac, toolchain extra_toolchain_mac, because platform
93+
// mac is listed first.
94+
addToolchain(
95+
"extra",
96+
"extra_toolchain_linux",
97+
ImmutableList.of("//constraints:linux"),
98+
ImmutableList.of("//constraints:linux"),
99+
"baz");
100+
addToolchain(
101+
"extra",
102+
"extra_toolchain_mac",
103+
ImmutableList.of("//constraints:mac"),
104+
ImmutableList.of("//constraints:linux"),
105+
"baz");
106+
rewriteWorkspace(
107+
"register_toolchains('//extra:extra_toolchain_linux', '//extra:extra_toolchain_mac')",
108+
"register_execution_platforms('//platforms:mac', '//platforms:linux')");
109+
110+
useConfiguration("--platforms=//platforms:linux");
111+
ToolchainContextKey key =
112+
ToolchainContextKey.key()
113+
.configurationKey(targetConfigKey)
114+
.toolchainTypes(testToolchainType)
115+
.build();
116+
117+
EvaluationResult<UnloadedToolchainContext> result = invokeToolchainResolution(key);
118+
119+
assertThatEvaluationResult(result).hasNoError();
120+
UnloadedToolchainContext unloadedToolchainContext = result.get(key);
121+
assertThat(unloadedToolchainContext).isNotNull();
122+
123+
assertThat(unloadedToolchainContext).hasToolchainType(testToolchainTypeLabel);
124+
assertThat(unloadedToolchainContext).hasResolvedToolchain("//extra:extra_toolchain_mac_impl");
125+
assertThat(unloadedToolchainContext).hasExecutionPlatform("//platforms:mac");
126+
assertThat(unloadedToolchainContext).hasTargetPlatform("//platforms:linux");
127+
}
128+
129+
@Test
130+
public void resolve_multiple() throws Exception {
131+
Label secondToolchainTypeLabel = Label.parseAbsoluteUnchecked("//second:toolchain_type");
132+
ToolchainTypeRequirement secondToolchainTypeRequirement =
133+
ToolchainTypeRequirement.create(secondToolchainTypeLabel);
134+
ToolchainTypeInfo secondToolchainTypeInfo = ToolchainTypeInfo.create(secondToolchainTypeLabel);
135+
scratch.file("second/BUILD", "toolchain_type(name = 'toolchain_type')");
136+
137+
addToolchain(
138+
"main",
139+
"main_toolchain_linux",
140+
ImmutableList.of("//constraints:linux"),
141+
ImmutableList.of("//constraints:linux"),
142+
"baz");
143+
addToolchain(
144+
"main",
145+
"second_toolchain_linux",
146+
secondToolchainTypeLabel,
147+
ImmutableList.of("//constraints:linux"),
148+
ImmutableList.of("//constraints:linux"),
149+
"baz");
150+
rewriteWorkspace(
151+
"register_toolchains('//main:all',)", "register_execution_platforms('//platforms:linux')");
152+
153+
useConfiguration("--platforms=//platforms:linux");
154+
ToolchainContextKey key =
155+
ToolchainContextKey.key()
156+
.configurationKey(targetConfigKey)
157+
.toolchainTypes(testToolchainType, secondToolchainTypeRequirement)
158+
.build();
159+
160+
EvaluationResult<UnloadedToolchainContext> result = invokeToolchainResolution(key);
161+
162+
assertThatEvaluationResult(result).hasNoError();
163+
UnloadedToolchainContext unloadedToolchainContext = result.get(key);
164+
assertThat(unloadedToolchainContext).isNotNull();
165+
166+
assertThat(unloadedToolchainContext).hasToolchainType(testToolchainTypeLabel);
167+
assertThat(unloadedToolchainContext).hasResolvedToolchain("//main:main_toolchain_linux_impl");
168+
assertThat(unloadedToolchainContext).hasToolchainType(secondToolchainTypeLabel);
169+
assertThat(unloadedToolchainContext).hasResolvedToolchain("//main:second_toolchain_linux_impl");
170+
assertThat(unloadedToolchainContext).hasExecutionPlatform("//platforms:linux");
171+
assertThat(unloadedToolchainContext).hasTargetPlatform("//platforms:linux");
172+
}
173+
174+
@Test
175+
public void resolve_mandatory_missing() throws Exception {
176+
// There is no toolchain for the requested type.
177+
useConfiguration("--platforms=//platforms:linux");
178+
ToolchainContextKey key =
179+
ToolchainContextKey.key()
180+
.configurationKey(targetConfigKey)
181+
.toolchainTypes(testToolchainType)
182+
.build();
183+
184+
EvaluationResult<UnloadedToolchainContext> result = invokeToolchainResolution(key);
185+
186+
assertThatEvaluationResult(result)
187+
.hasErrorEntryForKeyThat(key)
188+
.hasExceptionThat()
189+
.hasMessageThat()
190+
.contains("No matching toolchains found for types //toolchain:test_toolchain");
191+
}
192+
193+
@Test
194+
public void resolve_multiple_optional() throws Exception {
195+
Label secondToolchainTypeLabel = Label.parseAbsoluteUnchecked("//second:toolchain_type");
196+
ToolchainTypeRequirement secondToolchainTypeRequirement =
197+
ToolchainTypeRequirement.builder(secondToolchainTypeLabel).mandatory(false).build();
198+
ToolchainTypeInfo secondToolchainTypeInfo = ToolchainTypeInfo.create(secondToolchainTypeLabel);
199+
scratch.file("second/BUILD", "toolchain_type(name = 'toolchain_type')");
200+
201+
addToolchain(
202+
"main",
203+
"main_toolchain_linux",
204+
ImmutableList.of("//constraints:linux"),
205+
ImmutableList.of("//constraints:linux"),
206+
"baz");
207+
addToolchain(
208+
"main",
209+
"second_toolchain_linux",
210+
secondToolchainTypeLabel,
211+
ImmutableList.of("//constraints:linux"),
212+
ImmutableList.of("//constraints:linux"),
213+
"baz");
214+
rewriteWorkspace(
215+
"register_toolchains('//main:all',)", "register_execution_platforms('//platforms:linux')");
216+
217+
useConfiguration("--platforms=//platforms:linux");
218+
ToolchainContextKey key =
219+
ToolchainContextKey.key()
220+
.configurationKey(targetConfigKey)
221+
.toolchainTypes(testToolchainType, secondToolchainTypeRequirement)
222+
.build();
223+
224+
EvaluationResult<UnloadedToolchainContext> result = invokeToolchainResolution(key);
225+
226+
assertThatEvaluationResult(result).hasNoError();
227+
UnloadedToolchainContext unloadedToolchainContext = result.get(key);
228+
assertThat(unloadedToolchainContext).isNotNull();
229+
230+
assertThat(unloadedToolchainContext).hasToolchainType(testToolchainTypeLabel);
231+
assertThat(unloadedToolchainContext).hasResolvedToolchain("//main:main_toolchain_linux_impl");
232+
assertThat(unloadedToolchainContext).hasToolchainType(secondToolchainTypeLabel);
233+
assertThat(unloadedToolchainContext).hasResolvedToolchain("//main:second_toolchain_linux_impl");
234+
assertThat(unloadedToolchainContext).hasExecutionPlatform("//platforms:linux");
235+
assertThat(unloadedToolchainContext).hasTargetPlatform("//platforms:linux");
236+
}
237+
238+
@Test
239+
public void resolve_multiple_optional_missing() throws Exception {
240+
Label secondToolchainTypeLabel = Label.parseAbsoluteUnchecked("//second:toolchain_type");
241+
ToolchainTypeRequirement secondToolchainTypeRequirement =
242+
ToolchainTypeRequirement.builder(secondToolchainTypeLabel).mandatory(false).build();
243+
ToolchainTypeInfo secondToolchainTypeInfo = ToolchainTypeInfo.create(secondToolchainTypeLabel);
244+
scratch.file("second/BUILD", "toolchain_type(name = 'toolchain_type')");
245+
246+
addToolchain(
247+
"main",
248+
"main_toolchain_linux",
249+
ImmutableList.of("//constraints:linux"),
250+
ImmutableList.of("//constraints:linux"),
251+
"baz");
252+
rewriteWorkspace(
253+
"register_toolchains('//main:all',)", "register_execution_platforms('//platforms:linux')");
254+
255+
useConfiguration("--platforms=//platforms:linux");
256+
ToolchainContextKey key =
257+
ToolchainContextKey.key()
258+
.configurationKey(targetConfigKey)
259+
.toolchainTypes(testToolchainType, secondToolchainTypeRequirement)
260+
.build();
261+
262+
EvaluationResult<UnloadedToolchainContext> result = invokeToolchainResolution(key);
263+
264+
assertThatEvaluationResult(result).hasNoError();
265+
UnloadedToolchainContext unloadedToolchainContext = result.get(key);
266+
assertThat(unloadedToolchainContext).isNotNull();
267+
268+
assertThat(unloadedToolchainContext).hasToolchainType(testToolchainTypeLabel);
269+
assertThat(unloadedToolchainContext).hasResolvedToolchain("//main:main_toolchain_linux_impl");
270+
assertThat(unloadedToolchainContext).hasToolchainType(secondToolchainTypeLabel);
271+
assertThat(unloadedToolchainContext)
272+
.resolvedToolchainLabels()
273+
.doesNotContain(Label.parseAbsoluteUnchecked("//main:second_toolchain_linux_impl"));
274+
assertThat(unloadedToolchainContext).hasExecutionPlatform("//platforms:linux");
275+
assertThat(unloadedToolchainContext).hasTargetPlatform("//platforms:linux");
276+
}
277+
88278
@Test
89279
public void resolve_toolchainTypeAlias() throws Exception {
90280
addToolchain(

src/test/shell/bazel/toolchain_test.sh

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,8 @@ use_toolchain(
386386
message = 'this is the rule')
387387
EOF
388388

389-
bazel build //demo:use &> $TEST_log && fail "Build failure expected"
390-
expect_log 'While resolving toolchains for target //demo:use: no matching toolchains found for types //toolchain:test_toolchain'
389+
bazel build "//${pkg}/demo:use" &> $TEST_log && fail "Build failure expected"
390+
expect_log "While resolving toolchains for target //${pkg}/demo:use: No matching toolchains found for types //${pkg}/toolchain:test_toolchain."
391391
}
392392

393393
function test_multiple_toolchain_use_in_rule {
@@ -474,8 +474,8 @@ use_toolchains(
474474
message = 'this is the rule')
475475
EOF
476476

477-
bazel build //demo:use &> $TEST_log && fail "Build failure expected"
478-
expect_log 'While resolving toolchains for target //demo:use: no matching toolchains found for types //toolchain:test_toolchain_2'
477+
bazel build "//${pkg}/demo:use" &> $TEST_log && fail "Build failure expected"
478+
expect_log "While resolving toolchains for target //${pkg}/demo:use: No matching toolchains found for types //${pkg}/toolchain:test_toolchain_2."
479479
}
480480

481481
function test_toolchain_use_in_rule_non_required_toolchain {
@@ -721,10 +721,10 @@ EOF
721721

722722
# This should not match any toolchains.
723723
bazel build \
724-
--host_platform=//:platform1 \
725-
--platforms=//:platform1 \
726-
//demo:use &> $TEST_log && fail "Build failure expected"
727-
expect_log 'While resolving toolchains for target //demo:use: no matching toolchains found for types //toolchain:test_toolchain'
724+
--host_platform="//${pkg}:platform1" \
725+
--platforms="//${pkg}:platform1" \
726+
"//${pkg}/demo:use" &> $TEST_log && fail "Build failure expected"
727+
expect_log "While resolving toolchains for target //${pkg}/demo:use: No matching toolchains found for types //${pkg}/toolchain:test_toolchain."
728728
expect_not_log 'Using toolchain: rule message:'
729729
}
730730

0 commit comments

Comments
 (0)