blob: 40d6701c330546e89239fd28499db0611180be39 [file] [log] [blame]
John Cater2e56f062017-07-20 19:43:20 +02001// Copyright 2017 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.skyframe;
16
John Catere959e442018-02-28 07:52:21 -080017import static java.util.stream.Collectors.joining;
18
John Cater2e56f062017-07-20 19:43:20 +020019import com.google.auto.value.AutoValue;
20import com.google.common.base.Joiner;
John Catere959e442018-02-28 07:52:21 -080021import com.google.common.base.Optional;
22import com.google.common.collect.HashBasedTable;
John Cater2e56f062017-07-20 19:43:20 +020023import com.google.common.collect.ImmutableBiMap;
24import com.google.common.collect.ImmutableList;
John Catere959e442018-02-28 07:52:21 -080025import com.google.common.collect.Table;
John Cater2e56f062017-07-20 19:43:20 +020026import com.google.devtools.build.lib.analysis.ConfiguredTarget;
27import com.google.devtools.build.lib.analysis.PlatformConfiguration;
John Catere959e442018-02-28 07:52:21 -080028import com.google.devtools.build.lib.analysis.PlatformOptions;
John Cater2e56f062017-07-20 19:43:20 +020029import com.google.devtools.build.lib.analysis.ToolchainContext;
30import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
31import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
32import com.google.devtools.build.lib.analysis.platform.PlatformProviderUtils;
33import com.google.devtools.build.lib.cmdline.Label;
John Cater0084e162018-03-12 18:50:56 -070034import com.google.devtools.build.lib.cmdline.TargetParsingException;
John Catere959e442018-02-28 07:52:21 -080035import com.google.devtools.build.lib.events.Event;
John Cater0084e162018-03-12 18:50:56 -070036import com.google.devtools.build.lib.pkgcache.FilteringPolicy;
John Cater2e56f062017-07-20 19:43:20 +020037import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ConfiguredValueCreationException;
John Cater535daee2017-08-04 22:44:03 +020038import com.google.devtools.build.lib.skyframe.RegisteredToolchainsFunction.InvalidToolchainLabelException;
John Cater2e56f062017-07-20 19:43:20 +020039import com.google.devtools.build.lib.skyframe.ToolchainResolutionFunction.NoToolchainFoundException;
John Cater2e56f062017-07-20 19:43:20 +020040import com.google.devtools.build.lib.syntax.EvalException;
John Cater2e56f062017-07-20 19:43:20 +020041import com.google.devtools.build.skyframe.SkyFunction.Environment;
42import com.google.devtools.build.skyframe.SkyKey;
43import com.google.devtools.build.skyframe.ValueOrException;
44import com.google.devtools.build.skyframe.ValueOrException4;
45import java.util.ArrayList;
janakr95656662018-02-14 17:14:51 -080046import java.util.HashMap;
John Cater2e56f062017-07-20 19:43:20 +020047import java.util.List;
48import java.util.Map;
cpeyserfb829992017-09-07 17:17:03 +020049import java.util.Set;
John Cater5ee389c2017-08-30 20:07:32 +020050import javax.annotation.Nullable;
John Cater2e56f062017-07-20 19:43:20 +020051
52/**
53 * Common code to create a {@link ToolchainContext} given a set of required toolchain type labels.
54 */
55public class ToolchainUtil {
56
57 /**
58 * Returns a new {@link ToolchainContext}, with the correct toolchain labels based on the results
59 * of the {@link ToolchainResolutionFunction}.
60 */
John Cater5ee389c2017-08-30 20:07:32 +020061 @Nullable
janakr95656662018-02-14 17:14:51 -080062 static ToolchainContext createToolchainContext(
John Cater53a87b92017-08-01 00:53:39 +020063 Environment env,
64 String targetDescription,
cpeyserfb829992017-09-07 17:17:03 +020065 Set<Label> requiredToolchains,
John Catere959e442018-02-28 07:52:21 -080066 @Nullable BuildConfigurationValue.Key configurationKey)
John Cater2e56f062017-07-20 19:43:20 +020067 throws ToolchainContextException, InterruptedException {
John Cater73fd9972017-11-22 09:15:12 -080068
69 // In some cases this is called with a missing configuration, so we skip toolchain context.
janakr40d00772018-02-14 14:08:45 -080070 if (configurationKey == null) {
John Cater73fd9972017-11-22 09:15:12 -080071 return null;
72 }
73
John Catere959e442018-02-28 07:52:21 -080074 // This call could be combined with the call below, but this SkyFunction is evaluated so rarely
75 // it's not worth optimizing.
76 BuildConfigurationValue value = (BuildConfigurationValue) env.getValue(configurationKey);
77 if (env.valuesMissing()) {
78 return null;
79 }
80 BuildConfiguration configuration = value.getConfiguration();
John Cater73fd9972017-11-22 09:15:12 -080081
John Catere959e442018-02-28 07:52:21 -080082 // Load the target and host platform keys.
83 PlatformConfiguration platformConfiguration =
84 configuration.getFragment(PlatformConfiguration.class);
85 if (platformConfiguration == null) {
86 return null;
87 }
88 Label hostPlatformLabel = platformConfiguration.getHostPlatform();
89 Label targetPlatformLabel = platformConfiguration.getTargetPlatforms().get(0);
90
91 ConfiguredTargetKey hostPlatformKey = ConfiguredTargetKey.of(hostPlatformLabel, configuration);
92 ConfiguredTargetKey targetPlatformKey =
93 ConfiguredTargetKey.of(targetPlatformLabel, configuration);
94
95 // Load the host and target platforms early, to check for errors.
96 getPlatformInfo(ImmutableList.of(hostPlatformKey, targetPlatformKey), env);
97
98 // Load all available execution platform keys. This will find any errors in the execution
99 // platform definitions.
100 RegisteredExecutionPlatformsValue registeredExecutionPlatforms =
101 loadRegisteredExecutionPlatforms(env, configurationKey);
102 if (registeredExecutionPlatforms == null) {
John Cater73fd9972017-11-22 09:15:12 -0800103 return null;
104 }
105
John Catere959e442018-02-28 07:52:21 -0800106 ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys =
107 new ImmutableList.Builder<ConfiguredTargetKey>()
108 .addAll(registeredExecutionPlatforms.registeredExecutionPlatformKeys())
109 .add(hostPlatformKey)
110 .build();
111 Optional<ResolvedToolchains> resolvedToolchains =
John Cater93b32942018-02-06 07:25:19 -0800112 resolveToolchainLabels(
janakr95656662018-02-14 17:14:51 -0800113 env,
114 requiredToolchains,
John Catere959e442018-02-28 07:52:21 -0800115 configuration,
janakr95656662018-02-14 17:14:51 -0800116 configurationKey,
John Catere959e442018-02-28 07:52:21 -0800117 availableExecutionPlatformKeys,
118 targetPlatformKey);
119 if (resolvedToolchains == null) {
John Cater5ee389c2017-08-30 20:07:32 +0200120 return null;
121 }
John Cater73fd9972017-11-22 09:15:12 -0800122
John Catere959e442018-02-28 07:52:21 -0800123 if (resolvedToolchains.isPresent()) {
124 return createContext(
125 env,
126 targetDescription,
127 resolvedToolchains.get().executionPlatformKey(),
128 resolvedToolchains.get().targetPlatformKey(),
129 requiredToolchains,
130 resolvedToolchains.get().toolchains());
131 } else {
132 // No toolchain could be resolved, but no error happened, so fall back to host platform.
133 return createContext(
134 env,
135 targetDescription,
136 hostPlatformKey,
137 targetPlatformKey,
138 requiredToolchains,
139 ImmutableBiMap.of());
John Cater2e56f062017-07-20 19:43:20 +0200140 }
141 }
142
John Catere959e442018-02-28 07:52:21 -0800143 private static RegisteredExecutionPlatformsValue loadRegisteredExecutionPlatforms(
144 Environment env, BuildConfigurationValue.Key configurationKey)
145 throws InterruptedException, ToolchainContextException {
146 try {
147 RegisteredExecutionPlatformsValue registeredExecutionPlatforms =
148 (RegisteredExecutionPlatformsValue)
149 env.getValueOrThrow(
150 RegisteredExecutionPlatformsValue.key(configurationKey),
151 InvalidPlatformException.class);
152 if (registeredExecutionPlatforms == null) {
153 return null;
154 }
155 return registeredExecutionPlatforms;
156 } catch (InvalidPlatformException e) {
157 throw new ToolchainContextException(e);
John Cater77112c62017-09-25 10:58:41 -0400158 }
John Cater77112c62017-09-25 10:58:41 -0400159 }
160
John Cater5ee389c2017-08-30 20:07:32 +0200161 @Nullable
janakr95656662018-02-14 17:14:51 -0800162 static Map<ConfiguredTargetKey, PlatformInfo> getPlatformInfo(
John Catere959e442018-02-28 07:52:21 -0800163 Iterable<ConfiguredTargetKey> platformKeys, Environment env)
janakr95656662018-02-14 17:14:51 -0800164 throws InterruptedException, ToolchainContextException {
John Catere959e442018-02-28 07:52:21 -0800165
janakr95656662018-02-14 17:14:51 -0800166 Map<SkyKey, ValueOrException<ConfiguredValueCreationException>> values =
John Catere959e442018-02-28 07:52:21 -0800167 env.getValuesOrThrow(platformKeys, ConfiguredValueCreationException.class);
janakr95656662018-02-14 17:14:51 -0800168 boolean valuesMissing = env.valuesMissing();
169 Map<ConfiguredTargetKey, PlatformInfo> platforms = valuesMissing ? null : new HashMap<>();
170 try {
John Catere959e442018-02-28 07:52:21 -0800171 for (ConfiguredTargetKey key : platformKeys) {
172 PlatformInfo platformInfo = findPlatformInfo(values.get(key));
janakr95656662018-02-14 17:14:51 -0800173 if (!valuesMissing && platformInfo != null) {
174 platforms.put(key, platformInfo);
175 }
176 }
177 } catch (ConfiguredValueCreationException e) {
178 throw new ToolchainContextException(e);
179 }
180 if (valuesMissing) {
181 return null;
182 }
183 return platforms;
184 }
185
John Catere959e442018-02-28 07:52:21 -0800186 /**
187 * Returns the {@link PlatformInfo} provider from the {@link ConfiguredTarget} in the {@link
188 * ValueOrException}, or {@code null} if the {@link ConfiguredTarget} is not present. If the
189 * {@link ConfiguredTarget} does not have a {@link PlatformInfo} provider, a {@link
190 * InvalidPlatformException} is thrown, wrapped in a {@link ToolchainContextException}.
191 */
janakr95656662018-02-14 17:14:51 -0800192 @Nullable
John Catere959e442018-02-28 07:52:21 -0800193 private static PlatformInfo findPlatformInfo(
194 ValueOrException<ConfiguredValueCreationException> valueOrException)
195 throws ConfiguredValueCreationException, ToolchainContextException {
John Cater2e56f062017-07-20 19:43:20 +0200196
John Catere959e442018-02-28 07:52:21 -0800197 ConfiguredTargetValue ctv = (ConfiguredTargetValue) valueOrException.get();
198 if (ctv == null) {
janakr95656662018-02-14 17:14:51 -0800199 return null;
John Cater2e56f062017-07-20 19:43:20 +0200200 }
janakr95656662018-02-14 17:14:51 -0800201
John Catere959e442018-02-28 07:52:21 -0800202 ConfiguredTarget configuredTarget = ctv.getConfiguredTarget();
203 PlatformInfo platformInfo = PlatformProviderUtils.platform(configuredTarget);
204 if (platformInfo == null) {
205 throw new ToolchainContextException(
206 new InvalidPlatformException(configuredTarget.getLabel()));
207 }
208
209 return platformInfo;
210 }
211
212 /** Data class to hold the result of resolving toolchain labels. */
213 @AutoValue
214 protected abstract static class ResolvedToolchains {
215
216 abstract ConfiguredTargetKey executionPlatformKey();
217
218 abstract ConfiguredTargetKey targetPlatformKey();
219
220 abstract ImmutableBiMap<Label, Label> toolchains();
221
222 protected static ResolvedToolchains create(
223 ConfiguredTargetKey executionPlatformKey,
224 ConfiguredTargetKey targetPlatformKey,
225 Map<Label, Label> toolchains) {
226 return new AutoValue_ToolchainUtil_ResolvedToolchains(
227 executionPlatformKey, targetPlatformKey, ImmutableBiMap.copyOf(toolchains));
228 }
John Cater2e56f062017-07-20 19:43:20 +0200229 }
230
John Cater5ee389c2017-08-30 20:07:32 +0200231 @Nullable
John Catere959e442018-02-28 07:52:21 -0800232 private static Optional<ResolvedToolchains> resolveToolchainLabels(
John Cater73fd9972017-11-22 09:15:12 -0800233 Environment env,
234 Set<Label> requiredToolchains,
John Catere959e442018-02-28 07:52:21 -0800235 BuildConfiguration configuration,
janakr95656662018-02-14 17:14:51 -0800236 BuildConfigurationValue.Key configurationKey,
John Catere959e442018-02-28 07:52:21 -0800237 ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
janakr95656662018-02-14 17:14:51 -0800238 ConfiguredTargetKey targetPlatformKey)
John Cater2e56f062017-07-20 19:43:20 +0200239 throws InterruptedException, ToolchainContextException {
240
241 // If there are no required toolchains, bail out early.
242 if (requiredToolchains.isEmpty()) {
John Catere959e442018-02-28 07:52:21 -0800243 return Optional.absent();
John Cater2e56f062017-07-20 19:43:20 +0200244 }
245
John Cater2e56f062017-07-20 19:43:20 +0200246 // Find the toolchains for the required toolchain types.
John Catere959e442018-02-28 07:52:21 -0800247 List<ToolchainResolutionValue.Key> registeredToolchainKeys = new ArrayList<>();
John Cater2e56f062017-07-20 19:43:20 +0200248 for (Label toolchainType : requiredToolchains) {
249 registeredToolchainKeys.add(
250 ToolchainResolutionValue.key(
John Catere959e442018-02-28 07:52:21 -0800251 configurationKey, toolchainType, targetPlatformKey, availableExecutionPlatformKeys));
John Cater2e56f062017-07-20 19:43:20 +0200252 }
253
254 Map<
255 SkyKey,
256 ValueOrException4<
John Cater535daee2017-08-04 22:44:03 +0200257 NoToolchainFoundException, ConfiguredValueCreationException,
258 InvalidToolchainLabelException, EvalException>>
John Cater2e56f062017-07-20 19:43:20 +0200259 results =
260 env.getValuesOrThrow(
261 registeredToolchainKeys,
262 NoToolchainFoundException.class,
263 ConfiguredValueCreationException.class,
John Cater535daee2017-08-04 22:44:03 +0200264 InvalidToolchainLabelException.class,
John Cater2e56f062017-07-20 19:43:20 +0200265 EvalException.class);
John Cater77112c62017-09-25 10:58:41 -0400266 boolean valuesMissing = false;
John Cater2e56f062017-07-20 19:43:20 +0200267
John Catere959e442018-02-28 07:52:21 -0800268 // Determine the potential set of toolchains.
269 Table<ConfiguredTargetKey, Label, Label> resolvedToolchains = HashBasedTable.create();
John Cater2e56f062017-07-20 19:43:20 +0200270 List<Label> missingToolchains = new ArrayList<>();
271 for (Map.Entry<
272 SkyKey,
273 ValueOrException4<
John Cater535daee2017-08-04 22:44:03 +0200274 NoToolchainFoundException, ConfiguredValueCreationException,
275 InvalidToolchainLabelException, EvalException>>
John Cater2e56f062017-07-20 19:43:20 +0200276 entry : results.entrySet()) {
277 try {
278 Label requiredToolchainType =
John Catere959e442018-02-28 07:52:21 -0800279 ((ToolchainResolutionValue.Key) entry.getKey().argument()).toolchainType();
John Cater77112c62017-09-25 10:58:41 -0400280 ValueOrException4<
281 NoToolchainFoundException, ConfiguredValueCreationException,
282 InvalidToolchainLabelException, EvalException>
283 valueOrException = entry.getValue();
284 if (valueOrException.get() == null) {
285 valuesMissing = true;
John Catere959e442018-02-28 07:52:21 -0800286 continue;
John Cater77112c62017-09-25 10:58:41 -0400287 }
John Catere959e442018-02-28 07:52:21 -0800288
289 ToolchainResolutionValue toolchainResolutionValue =
290 (ToolchainResolutionValue) valueOrException.get();
291 addPlatformsAndLabels(resolvedToolchains, requiredToolchainType, toolchainResolutionValue);
John Cater2e56f062017-07-20 19:43:20 +0200292 } catch (NoToolchainFoundException e) {
293 // Save the missing type and continue looping to check for more.
294 missingToolchains.add(e.missingToolchainType());
295 } catch (ConfiguredValueCreationException e) {
296 throw new ToolchainContextException(e);
John Cater535daee2017-08-04 22:44:03 +0200297 } catch (InvalidToolchainLabelException e) {
John Cater2e56f062017-07-20 19:43:20 +0200298 throw new ToolchainContextException(e);
299 } catch (EvalException e) {
300 throw new ToolchainContextException(e);
301 }
302 }
303
304 if (!missingToolchains.isEmpty()) {
305 throw new ToolchainContextException(new UnresolvedToolchainsException(missingToolchains));
306 }
307
John Cater6738c362017-10-20 22:03:00 +0200308 if (valuesMissing) {
309 return null;
310 }
311
John Catere959e442018-02-28 07:52:21 -0800312 boolean debug = configuration.getOptions().get(PlatformOptions.class).toolchainResolutionDebug;
313
314 // Find and return the first execution platform which has all required toolchains.
315 for (ConfiguredTargetKey executionPlatformKey : availableExecutionPlatformKeys) {
316 // PlatformInfo executionPlatform = platforms.get(executionPlatformKey);
317 Map<Label, Label> toolchains = resolvedToolchains.row(executionPlatformKey);
318 if (!toolchains.keySet().containsAll(requiredToolchains)) {
319 // Not all toolchains are present, keep going
320 continue;
321 }
322
323 if (debug) {
324 env.getListener()
325 .handle(
326 Event.info(
327 String.format(
328 "ToolchainUtil: Selected execution platform %s, %s",
329 executionPlatformKey.getLabel(),
330 toolchains
331 .entrySet()
332 .stream()
333 .map(
334 e ->
335 String.format(
336 "type %s -> toolchain %s", e.getKey(), e.getValue()))
337 .collect(joining(", ")))));
338 }
339 return Optional.of(
340 ResolvedToolchains.create(executionPlatformKey, targetPlatformKey, toolchains));
341 }
342
343 return Optional.absent();
344 }
345
346 private static void addPlatformsAndLabels(
347 Table<ConfiguredTargetKey, Label, Label> resolvedToolchains,
348 Label requiredToolchainType,
349 ToolchainResolutionValue toolchainResolutionValue) {
350
351 for (Map.Entry<ConfiguredTargetKey, Label> entry :
352 toolchainResolutionValue.availableToolchainLabels().entrySet()) {
353 resolvedToolchains.put(entry.getKey(), requiredToolchainType, entry.getValue());
354 }
355 }
356
357 @Nullable
358 private static ToolchainContext createContext(
359 Environment env,
360 String targetDescription,
361 ConfiguredTargetKey executionPlatformKey,
362 ConfiguredTargetKey targetPlatformKey,
363 Set<Label> requiredToolchains,
364 ImmutableBiMap<Label, Label> toolchains)
365 throws ToolchainContextException, InterruptedException {
366
367 Map<ConfiguredTargetKey, PlatformInfo> platforms =
368 getPlatformInfo(ImmutableList.of(executionPlatformKey, targetPlatformKey), env);
369
370 if (platforms == null) {
371 return null;
372 }
373
374 return ToolchainContext.create(
375 targetDescription,
376 platforms.get(executionPlatformKey),
377 platforms.get(targetPlatformKey),
378 requiredToolchains,
379 toolchains);
John Cater2e56f062017-07-20 19:43:20 +0200380 }
381
John Cater0084e162018-03-12 18:50:56 -0700382 @Nullable
383 static ImmutableList<Label> expandTargetPatterns(
384 Environment env, List<String> targetPatterns, FilteringPolicy filteringPolicy)
385 throws InvalidTargetPatternException, InterruptedException {
386
387 // First parse the patterns, and throw any errors immediately.
388 List<TargetPatternValue.TargetPatternKey> patternKeys = new ArrayList<>();
389 for (TargetPatternValue.TargetPatternSkyKeyOrException keyOrException :
390 TargetPatternValue.keys(targetPatterns, filteringPolicy, "")) {
391
392 try {
393 patternKeys.add(keyOrException.getSkyKey());
394 } catch (TargetParsingException e) {
395 throw new InvalidTargetPatternException(keyOrException.getOriginalPattern(), e);
396 }
397 }
398
399 // Then, resolve the patterns.
John Cater0084e162018-03-12 18:50:56 -0700400 Map<SkyKey, ValueOrException<TargetParsingException>> resolvedPatterns =
401 env.getValuesOrThrow(patternKeys, TargetParsingException.class);
John Caterc36d4e82018-04-12 08:43:28 -0700402 boolean valuesMissing = env.valuesMissing();
403 ImmutableList.Builder<Label> labels = valuesMissing ? null : new ImmutableList.Builder<>();
John Cater0084e162018-03-12 18:50:56 -0700404
405 for (TargetPatternValue.TargetPatternKey pattern : patternKeys) {
406 TargetPatternValue value;
407 try {
408 value = (TargetPatternValue) resolvedPatterns.get(pattern).get();
John Caterc36d4e82018-04-12 08:43:28 -0700409 if (!valuesMissing && value != null) {
410 labels.addAll(value.getTargets().getTargets());
411 }
John Cater0084e162018-03-12 18:50:56 -0700412 } catch (TargetParsingException e) {
413 throw new InvalidTargetPatternException(pattern.getPattern(), e);
414 }
415 }
416
John Caterc36d4e82018-04-12 08:43:28 -0700417 if (valuesMissing) {
418 return null;
419 }
420
John Cater0084e162018-03-12 18:50:56 -0700421 return labels.build();
422 }
423
424 /**
425 * Exception used when an error occurs in {@link #expandTargetPatterns(Environment, List,
426 * FilteringPolicy)}.
427 */
428 static final class InvalidTargetPatternException extends Exception {
429 private String invalidPattern;
430 private TargetParsingException tpe;
431
432 public InvalidTargetPatternException(String invalidPattern, TargetParsingException tpe) {
433 super(tpe);
434 this.invalidPattern = invalidPattern;
435 this.tpe = tpe;
436 }
437
438 public String getInvalidPattern() {
439 return invalidPattern;
440 }
441
442 public TargetParsingException getTpe() {
443 return tpe;
444 }
445 }
446
John Cater5ee389c2017-08-30 20:07:32 +0200447 /** Exception used when a platform label is not a valid platform. */
janakrd65be8c2018-02-14 11:55:24 -0800448 static final class InvalidPlatformException extends Exception {
John Catere959e442018-02-28 07:52:21 -0800449 InvalidPlatformException(Label label) {
450 super(formatError(label));
451 }
452
453 InvalidPlatformException(Label label, ConfiguredValueCreationException e) {
454 super(formatError(label), e);
455 }
456
457 private static String formatError(Label label) {
458 return String.format(
459 "Target %s was referenced as a platform, but does not provide PlatformInfo", label);
John Cater5ee389c2017-08-30 20:07:32 +0200460 }
461 }
462
John Cater2e56f062017-07-20 19:43:20 +0200463 /** Exception used when a toolchain type is required but no matching toolchain is found. */
464 public static final class UnresolvedToolchainsException extends Exception {
465 private final ImmutableList<Label> missingToolchainTypes;
466
467 public UnresolvedToolchainsException(List<Label> missingToolchainTypes) {
468 super(
469 String.format(
470 "no matching toolchains found for types %s",
471 Joiner.on(", ").join(missingToolchainTypes)));
472 this.missingToolchainTypes = ImmutableList.copyOf(missingToolchainTypes);
473 }
474
475 public ImmutableList<Label> missingToolchainTypes() {
476 return missingToolchainTypes;
477 }
478 }
479
480 /** Exception used to wrap exceptions during toolchain resolution. */
481 public static class ToolchainContextException extends Exception {
John Cater5ee389c2017-08-30 20:07:32 +0200482 public ToolchainContextException(InvalidPlatformException e) {
483 super(e);
484 }
485
John Cater2e56f062017-07-20 19:43:20 +0200486 public ToolchainContextException(UnresolvedToolchainsException e) {
487 super(e);
488 }
489
490 public ToolchainContextException(ConfiguredValueCreationException e) {
491 super(e);
492 }
493
John Cater535daee2017-08-04 22:44:03 +0200494 public ToolchainContextException(InvalidToolchainLabelException e) {
John Cater2e56f062017-07-20 19:43:20 +0200495 super(e);
496 }
497
498 public ToolchainContextException(EvalException e) {
499 super(e);
500 }
501 }
502}