Use platform mappings.
Applying platform mapping to all BuildConfigurationValue.Key instances. This will cause all configurations to apply the platform mapping before being loaded.
Step 7/N towards the platforms mapping functionality for https://github.com/bazelbuild/bazel/issues/6426
RELNOTES: New platform_mappings ability to allow gradual flag to platforms/toolchains migration. See also https://github.com/bazelbuild/bazel/issues/6426
PiperOrigin-RevId: 244731653
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
index e99e9a7..9f224bb 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
@@ -22,6 +22,7 @@
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
import com.google.devtools.build.lib.analysis.config.ConfigurationResolver;
+import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.config.TransitionResolver;
import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
@@ -183,7 +184,8 @@
Collection<Target> targets,
ExtendedEventHandler eventHandler,
ConfiguredRuleClassProvider ruleClassProvider,
- SkyframeExecutor skyframeExecutor) {
+ SkyframeExecutor skyframeExecutor)
+ throws InvalidConfigurationException {
// We use a hash set here to remove duplicate nodes; this can happen for input files and package
// groups.
LinkedHashSet<TargetAndConfiguration> nodes = new LinkedHashSet<>(targets.size());
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java
index d71e03c..6adfaae6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java
@@ -30,6 +30,7 @@
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.Dependency;
import com.google.devtools.build.lib.analysis.DependencyResolver.DependencyKind;
+import com.google.devtools.build.lib.analysis.PlatformOptions;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
@@ -47,14 +48,17 @@
import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetValue;
+import com.google.devtools.build.lib.skyframe.PlatformMappingValue;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.build.lib.skyframe.TransitiveTargetKey;
import com.google.devtools.build.lib.skyframe.TransitiveTargetValue;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
+import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.ValueOrException;
+import com.google.devtools.common.options.OptionsParsingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -261,20 +265,38 @@
}
// If we get here, we have to get the configuration from Skyframe.
- for (BuildOptions options : toOptions) {
- if (sameFragments) {
- keysToEntries.put(
- BuildConfigurationValue.key(
- currentConfiguration.fragmentClasses(),
- BuildOptions.diffForReconstruction(defaultBuildOptions, options)),
- depsEntry);
+ PathFragment platformMappingPath =
+ currentConfiguration.getOptions().get(PlatformOptions.class).platformMappings;
+ PlatformMappingValue platformMappingValue =
+ (PlatformMappingValue) env.getValue(PlatformMappingValue.Key.create(platformMappingPath));
+ if (platformMappingValue == null) {
+ return null;
+ }
- } else {
- keysToEntries.put(
- BuildConfigurationValue.key(
- depFragments, BuildOptions.diffForReconstruction(defaultBuildOptions, options)),
- depsEntry);
+ try {
+ for (BuildOptions options : toOptions) {
+ if (sameFragments) {
+ keysToEntries.put(
+ BuildConfigurationValue.keyWithPlatformMapping(
+ platformMappingValue,
+ defaultBuildOptions,
+ currentConfiguration.fragmentClasses(),
+ BuildOptions.diffForReconstruction(defaultBuildOptions, options)),
+ depsEntry);
+
+ } else {
+ keysToEntries.put(
+ BuildConfigurationValue.keyWithPlatformMapping(
+ platformMappingValue,
+ defaultBuildOptions,
+ depFragments,
+ BuildOptions.diffForReconstruction(defaultBuildOptions, options)),
+ depsEntry);
+ }
}
+ } catch (OptionsParsingException e) {
+ throw new ConfiguredTargetFunction.DependencyEvaluationException(
+ new InvalidConfigurationException(e));
}
}
@@ -631,7 +653,8 @@
Iterable<TargetAndConfiguration> defaultContext,
Multimap<BuildConfiguration, Dependency> targetsToEvaluate,
ExtendedEventHandler eventHandler,
- SkyframeExecutor skyframeExecutor) {
+ SkyframeExecutor skyframeExecutor)
+ throws InvalidConfigurationException {
Map<Label, Target> labelsToTargets = new LinkedHashMap<>();
for (TargetAndConfiguration targetAndConfig : defaultContext) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java
index 90479a9..924a601 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java
@@ -26,10 +26,10 @@
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
+import com.google.devtools.common.options.OptionsParsingException;
import java.io.Serializable;
import java.util.Objects;
import java.util.Set;
-import java.util.logging.Logger;
/** A Skyframe value representing a {@link BuildConfiguration}. */
// TODO(bazel-team): mark this immutable when BuildConfiguration is immutable.
@@ -37,7 +37,6 @@
@AutoCodec
@ThreadSafe
public class BuildConfigurationValue implements SkyValue {
- private static final Logger logger = Logger.getLogger(BuildConfigurationValue.class.getName());
private final BuildConfiguration configuration;
BuildConfigurationValue(BuildConfiguration configuration) {
@@ -49,14 +48,61 @@
}
/**
+ * Creates a new configuration key based on the given diff, after applying a platform mapping
+ * transformation.
+ *
+ * @param platformMappingValue sky value that can transform a configuration key based on a
+ * platform mapping
+ * @param defaultBuildOptions set of native build options without modifications based on parsing
+ * flags
+ * @param fragments set of options fragments this configuration should cover
+ * @param optionsDiff diff between the default options and the desired configuration
+ * @throws OptionsParsingException if the platform mapping cannot be parsed
+ */
+ public static Key keyWithPlatformMapping(
+ PlatformMappingValue platformMappingValue,
+ BuildOptions defaultBuildOptions,
+ FragmentClassSet fragments,
+ BuildOptions.OptionsDiffForReconstruction optionsDiff)
+ throws OptionsParsingException {
+ return platformMappingValue.map(
+ keyWithoutPlatformMapping(fragments, optionsDiff), defaultBuildOptions);
+ }
+
+ /**
+ * Creates a new configuration key based on the given diff, after applying a platform mapping
+ * transformation.
+ *
+ * @param platformMappingValue sky value that can transform a configuration key based on a
+ * platform mapping
+ * @param defaultBuildOptions set of native build options without modifications based on parsing
+ * flags
+ * @param fragments set of options fragments this configuration should cover
+ * @param optionsDiff diff between the default options and the desired configuration
+ * @throws OptionsParsingException if the platform mapping cannot be parsed
+ */
+ public static Key keyWithPlatformMapping(
+ PlatformMappingValue platformMappingValue,
+ BuildOptions defaultBuildOptions,
+ Set<Class<? extends BuildConfiguration.Fragment>> fragments,
+ BuildOptions.OptionsDiffForReconstruction optionsDiff)
+ throws OptionsParsingException {
+ return platformMappingValue.map(
+ keyWithoutPlatformMapping(fragments, optionsDiff), defaultBuildOptions);
+ }
+
+ /**
* Returns the key for a requested configuration.
*
+ * <p>Callers are responsible for applying the platform mapping or ascertaining that a platform
+ * mapping is not required.
+ *
* @param fragments the fragments the configuration should contain
* @param optionsDiff the {@link BuildOptions.OptionsDiffForReconstruction} object the {@link
* BuildOptions} should be rebuilt from
*/
@ThreadSafe
- public static Key key(
+ static Key keyWithoutPlatformMapping(
Set<Class<? extends BuildConfiguration.Fragment>> fragments,
BuildOptions.OptionsDiffForReconstruction optionsDiff) {
return Key.create(
@@ -65,13 +111,23 @@
optionsDiff);
}
- public static Key key(
+ private static Key keyWithoutPlatformMapping(
FragmentClassSet fragmentClassSet, BuildOptions.OptionsDiffForReconstruction optionsDiff) {
return Key.create(fragmentClassSet, optionsDiff);
}
+ /**
+ * Returns a configuration key for the given configuration.
+ *
+ * <p>Note that this key creation method does not apply a platform mapping, it is assumed that the
+ * passed configuration was created with one such and thus its key does not need to be mapped
+ * again.
+ *
+ * @param buildConfiguration configuration whose key is requested
+ */
public static Key key(BuildConfiguration buildConfiguration) {
- return key(buildConfiguration.fragmentClasses(), buildConfiguration.getBuildOptionsDiff());
+ return keyWithoutPlatformMapping(
+ buildConfiguration.fragmentClasses(), buildConfiguration.getBuildOptionsDiff());
}
/** {@link SkyKey} for {@link BuildConfigurationValue}. */
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PlatformMappingValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PlatformMappingValue.java
index db9fb4c..9f37b18 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PlatformMappingValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PlatformMappingValue.java
@@ -228,7 +228,7 @@
}
}
- return BuildConfigurationValue.key(
+ return BuildConfigurationValue.keyWithoutPlatformMapping(
original.getFragments(),
BuildOptions.diffForReconstruction(defaultBuildOptions, modifiedOptions));
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareAnalysisPhaseFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareAnalysisPhaseFunction.java
index 98850f4..06fed8a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareAnalysisPhaseFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareAnalysisPhaseFunction.java
@@ -23,6 +23,7 @@
import com.google.devtools.build.lib.analysis.AnalysisUtils;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.Dependency;
+import com.google.devtools.build.lib.analysis.PlatformOptions;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
@@ -40,11 +41,13 @@
import com.google.devtools.build.lib.packages.NoSuchThingException;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.skyframe.PrepareAnalysisPhaseValue.PrepareAnalysisPhaseKey;
+import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.ValueOrException;
+import com.google.devtools.common.options.OptionsParsingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -82,19 +85,36 @@
ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> allFragments =
options.getFragments().fragmentClasses();
- BuildConfigurationValue.Key hostConfigurationKey =
- BuildConfigurationValue.key(
- allFragments,
- BuildOptions.diffForReconstruction(defaultBuildOptions, hostOptions));
- ImmutableList<BuildConfigurationValue.Key> targetConfigurationKeys =
- getTopLevelBuildOptions(targetOptions, options.getMultiCpu())
- .stream()
- .map(
- elem ->
- BuildConfigurationValue.key(
- allFragments,
- BuildOptions.diffForReconstruction(defaultBuildOptions, elem)))
- .collect(ImmutableList.toImmutableList());
+
+ PathFragment platformMappingPath = targetOptions.get(PlatformOptions.class).platformMappings;
+ PlatformMappingValue platformMappingValue =
+ (PlatformMappingValue) env.getValue(PlatformMappingValue.Key.create(platformMappingPath));
+ if (platformMappingValue == null) {
+ return null;
+ }
+
+ BuildConfigurationValue.Key hostConfigurationKey = null;
+ ImmutableList.Builder<BuildConfigurationValue.Key> targetConfigurationKeysBuilder =
+ ImmutableList.builder();
+ try {
+ hostConfigurationKey =
+ BuildConfigurationValue.keyWithPlatformMapping(
+ platformMappingValue,
+ defaultBuildOptions,
+ allFragments,
+ BuildOptions.diffForReconstruction(defaultBuildOptions, hostOptions));
+ for (BuildOptions buildOptions :
+ getTopLevelBuildOptions(targetOptions, options.getMultiCpu())) {
+ targetConfigurationKeysBuilder.add(
+ BuildConfigurationValue.keyWithPlatformMapping(
+ platformMappingValue,
+ defaultBuildOptions,
+ allFragments,
+ BuildOptions.diffForReconstruction(defaultBuildOptions, buildOptions)));
+ }
+ } catch (OptionsParsingException e) {
+ throw new PrepareAnalysisPhaseFunctionException(new InvalidConfigurationException(e));
+ }
// We don't need the host configuration below, but we call this to get the error, if any.
try {
@@ -103,6 +123,8 @@
throw new PrepareAnalysisPhaseFunctionException(e);
}
+ ImmutableList<BuildConfigurationValue.Key> targetConfigurationKeys =
+ targetConfigurationKeysBuilder.build();
Map<SkyKey, SkyValue> configs = env.getValues(targetConfigurationKeys);
// We only report invalid options for the target configurations, and abort if there's an error.
@@ -148,7 +170,7 @@
LinkedHashSet<TargetAndConfiguration> topLevelTargetsWithConfigs;
try {
topLevelTargetsWithConfigs = resolveConfigurations(env, nodes, asDeps);
- } catch (TransitionException e) {
+ } catch (TransitionException | OptionsParsingException e) {
throw new PrepareAnalysisPhaseFunctionException(new InvalidConfigurationException(e));
}
if (env.valuesMissing()) {
@@ -189,7 +211,7 @@
SkyFunction.Environment env,
Iterable<TargetAndConfiguration> nodes,
Multimap<BuildConfiguration, Dependency> asDeps)
- throws InterruptedException, TransitionException {
+ throws InterruptedException, TransitionException, OptionsParsingException {
Map<Label, Target> labelsToTargets = new LinkedHashMap<>();
for (TargetAndConfiguration node : nodes) {
labelsToTargets.put(node.getTarget().getLabel(), node.getTarget());
@@ -244,7 +266,7 @@
// Note: this implementation runs inside Skyframe, so it has access to SkyFunction.Environment.
private Multimap<Dependency, BuildConfiguration> getConfigurations(
SkyFunction.Environment env, BuildOptions fromOptions, Iterable<Dependency> keys)
- throws InterruptedException, TransitionException {
+ throws InterruptedException, TransitionException, OptionsParsingException {
Multimap<Dependency, BuildConfiguration> builder =
ArrayListMultimap.<Dependency, BuildConfiguration>create();
Set<Dependency> depsToEvaluate = new HashSet<>();
@@ -295,6 +317,13 @@
}
// Now get the configurations.
+ PathFragment platformMappingPath = fromOptions.get(PlatformOptions.class).platformMappings;
+ PlatformMappingValue platformMappingValue =
+ (PlatformMappingValue) env.getValue(PlatformMappingValue.Key.create(platformMappingPath));
+ if (platformMappingValue == null) {
+ return null;
+ }
+
final List<SkyKey> configSkyKeys = new ArrayList<>();
for (Dependency key : keys) {
if (labelsWithErrors.contains(key.getLabel()) || key.hasExplicitConfiguration()) {
@@ -306,6 +335,7 @@
ConfigurationTransition transition = key.getTransition();
ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> depFragments =
fragmentsMap.get(key.getLabel());
+
if (depFragments != null) {
// TODO(juliexxia): combine these skyframe calls with other skyframe calls for this
// configured target.
@@ -333,8 +363,11 @@
StarlarkTransition.replayEvents(env.getListener(), transition);
for (BuildOptions toOption : toOptions) {
configSkyKeys.add(
- BuildConfigurationValue.key(
- depFragments, BuildOptions.diffForReconstruction(defaultBuildOptions, toOption)));
+ BuildConfigurationValue.keyWithPlatformMapping(
+ platformMappingValue,
+ defaultBuildOptions,
+ depFragments,
+ BuildOptions.diffForReconstruction(defaultBuildOptions, toOption)));
}
}
}
@@ -376,8 +409,11 @@
buildSettingOutputPackages);
for (BuildOptions toOption : toOptions) {
SkyKey configKey =
- BuildConfigurationValue.key(
- depFragments, BuildOptions.diffForReconstruction(defaultBuildOptions, toOption));
+ BuildConfigurationValue.keyWithPlatformMapping(
+ platformMappingValue,
+ defaultBuildOptions,
+ depFragments,
+ BuildOptions.diffForReconstruction(defaultBuildOptions, toOption));
BuildConfigurationValue configValue =
((BuildConfigurationValue) configsResult.get(configKey));
// configValue will be null here if there was an exception thrown during configuration
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 04b5338..b6450dc 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -67,6 +67,7 @@
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.Dependency;
+import com.google.devtools.build.lib.analysis.PlatformOptions;
import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory;
@@ -176,6 +177,7 @@
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.WalkableGraph.WalkableGraphFactory;
+import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.OptionsProvider;
import java.io.PrintStream;
import java.math.BigInteger;
@@ -1451,6 +1453,7 @@
getConfigurations(
eventHandler,
PrepareAnalysisPhaseFunction.getTopLevelBuildOptions(buildOptions, multiCpu),
+ buildOptions,
keepGoing);
BuildConfiguration firstTargetConfig = topLevelTargetConfigs.get(0);
@@ -1603,7 +1606,8 @@
public ImmutableList<ConfiguredTargetAndData> getConfiguredTargetsForTesting(
ExtendedEventHandler eventHandler,
BuildConfiguration originalConfig,
- Iterable<Dependency> keys) {
+ Iterable<Dependency> keys)
+ throws TransitionException, InvalidConfigurationException {
return getConfiguredTargetMapForTesting(eventHandler, originalConfig, keys).values().asList();
}
@@ -1619,7 +1623,8 @@
public ImmutableList<ConfiguredTargetAndData> getConfiguredTargetsForTesting(
ExtendedEventHandler eventHandler,
BuildConfigurationValue.Key originalConfig,
- Iterable<Dependency> keys) {
+ Iterable<Dependency> keys)
+ throws TransitionException, InvalidConfigurationException {
return getConfiguredTargetMapForTesting(eventHandler, originalConfig, keys).values().asList();
}
@@ -1636,7 +1641,8 @@
public ImmutableMultimap<Dependency, ConfiguredTargetAndData> getConfiguredTargetMapForTesting(
ExtendedEventHandler eventHandler,
BuildConfigurationValue.Key originalConfig,
- Iterable<Dependency> keys) {
+ Iterable<Dependency> keys)
+ throws TransitionException, InvalidConfigurationException {
return getConfiguredTargetMapForTesting(
eventHandler, getConfiguration(eventHandler, originalConfig), keys);
}
@@ -1654,7 +1660,8 @@
private ImmutableMultimap<Dependency, ConfiguredTargetAndData> getConfiguredTargetMapForTesting(
ExtendedEventHandler eventHandler,
BuildConfiguration originalConfig,
- Iterable<Dependency> keys) {
+ Iterable<Dependency> keys)
+ throws TransitionException, InvalidConfigurationException {
checkActive();
Multimap<Dependency, BuildConfiguration> configs;
@@ -1810,7 +1817,7 @@
ExtendedEventHandler eventHandler, BuildOptions options, boolean keepGoing)
throws InvalidConfigurationException {
return Iterables.getOnlyElement(
- getConfigurations(eventHandler, ImmutableList.of(options), keepGoing));
+ getConfigurations(eventHandler, ImmutableList.of(options), options, keepGoing));
}
@VisibleForTesting
@@ -1840,8 +1847,11 @@
* @throws InvalidConfigurationException if any build options produces an invalid configuration
*/
// TODO(ulfjack): Remove this legacy method after switching to the Skyframe-based implementation.
- public List<BuildConfiguration> getConfigurations(
- ExtendedEventHandler eventHandler, List<BuildOptions> optionsList, boolean keepGoing)
+ private List<BuildConfiguration> getConfigurations(
+ ExtendedEventHandler eventHandler,
+ List<BuildOptions> optionsList,
+ BuildOptions referenceBuildOptions,
+ boolean keepGoing)
throws InvalidConfigurationException {
Preconditions.checkArgument(!Iterables.isEmpty(optionsList));
@@ -1852,14 +1862,16 @@
.map(factory -> factory.creates())
.collect(
ImmutableSortedSet.toImmutableSortedSet(BuildConfiguration.lexicalFragmentSorter));
- final ImmutableList<SkyKey> configSkyKeys =
- optionsList.stream()
- .map(
- elem ->
- BuildConfigurationValue.key(
- allFragments,
- BuildOptions.diffForReconstruction(defaultBuildOptions, elem)))
- .collect(ImmutableList.toImmutableList());
+
+ PlatformMappingValue platformMappingValue =
+ getPlatformMappingValue(eventHandler, referenceBuildOptions);
+
+ ImmutableList.Builder<SkyKey> configSkyKeysBuilder = ImmutableList.builder();
+ for (BuildOptions options : optionsList) {
+ configSkyKeysBuilder.add(toConfigurationKey(platformMappingValue, allFragments, options));
+ }
+
+ ImmutableList<SkyKey> configSkyKeys = configSkyKeysBuilder.build();
// Skyframe-evaluate the configurations and throw errors if any.
EvaluationResult<SkyValue> evalResult = evaluateSkyKeys(eventHandler, configSkyKeys, keepGoing);
@@ -1898,14 +1910,15 @@
// Keep this in sync with {@link PrepareAnalysisPhaseFunction#getConfigurations}.
// TODO(ulfjack): Remove this legacy method after switching to the Skyframe-based implementation.
public Multimap<Dependency, BuildConfiguration> getConfigurations(
- ExtendedEventHandler eventHandler, BuildOptions fromOptions, Iterable<Dependency> keys) {
+ ExtendedEventHandler eventHandler, BuildOptions fromOptions, Iterable<Dependency> keys)
+ throws InvalidConfigurationException {
Multimap<Dependency, BuildConfiguration> builder =
ArrayListMultimap.<Dependency, BuildConfiguration>create();
Set<Dependency> depsToEvaluate = new HashSet<>();
ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> allFragments = null;
if (useUntrimmedConfigs(fromOptions)) {
- allFragments = ((ConfiguredRuleClassProvider) ruleClassProvider).getAllFragments();
+ allFragments = ruleClassProvider.getAllFragments();
}
// Get the fragments needed for dynamic configuration nodes.
@@ -1944,6 +1957,8 @@
}
}
+ PlatformMappingValue platformMappingValue = getPlatformMappingValue(eventHandler, fromOptions);
+
// Now get the configurations.
final List<SkyKey> configSkyKeys = new ArrayList<>();
for (Dependency key : keys) {
@@ -1979,9 +1994,7 @@
eventHandler.handle(Event.error(e.getMessage()));
}
for (BuildOptions toOption : toOptions) {
- configSkyKeys.add(
- BuildConfigurationValue.key(
- depFragments, BuildOptions.diffForReconstruction(defaultBuildOptions, toOption)));
+ configSkyKeys.add(toConfigurationKey(platformMappingValue, depFragments, toOption));
}
}
}
@@ -2018,9 +2031,8 @@
eventHandler.handle(Event.error(e.getMessage()));
}
for (BuildOptions toOption : toOptions) {
- SkyKey configKey =
- BuildConfigurationValue.key(
- depFragments, BuildOptions.diffForReconstruction(defaultBuildOptions, toOption));
+ BuildConfigurationValue.Key configKey =
+ toConfigurationKey(platformMappingValue, depFragments, toOption);
BuildConfigurationValue configValue =
((BuildConfigurationValue) configsResult.get(configKey));
// configValue will be null here if there was an exception thrown during configuration
@@ -2034,6 +2046,38 @@
return builder;
}
+ private PlatformMappingValue getPlatformMappingValue(
+ ExtendedEventHandler eventHandler, BuildOptions referenceBuildOptions)
+ throws InvalidConfigurationException {
+ PathFragment platformMappingPath =
+ referenceBuildOptions.get(PlatformOptions.class).platformMappings;
+
+ PlatformMappingValue.Key platformMappingKey =
+ PlatformMappingValue.Key.create(platformMappingPath);
+ EvaluationResult<SkyValue> evaluationResult =
+ evaluateSkyKeys(eventHandler, ImmutableSet.of(platformMappingKey));
+ if (evaluationResult.hasError()) {
+ throw new InvalidConfigurationException(evaluationResult.getError().getException());
+ }
+ return (PlatformMappingValue) evaluationResult.get(platformMappingKey);
+ }
+
+ private BuildConfigurationValue.Key toConfigurationKey(
+ PlatformMappingValue platformMappingValue,
+ ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> depFragments,
+ BuildOptions toOption)
+ throws InvalidConfigurationException {
+ try {
+ return BuildConfigurationValue.keyWithPlatformMapping(
+ platformMappingValue,
+ defaultBuildOptions,
+ depFragments,
+ BuildOptions.diffForReconstruction(defaultBuildOptions, toOption));
+ } catch (OptionsParsingException e) {
+ throw new InvalidConfigurationException(e);
+ }
+ }
+
private Map<SkyKey, SkyValue> collectBuildSettingValues(
ConfigurationTransition transition,
ExtendedEventHandler eventHandler,
@@ -2104,10 +2148,13 @@
@VisibleForTesting
public BuildConfiguration getConfigurationForTesting(
ExtendedEventHandler eventHandler, FragmentClassSet fragments, BuildOptions options)
- throws InterruptedException {
+ throws InterruptedException, OptionsParsingException, InvalidConfigurationException {
SkyKey key =
- BuildConfigurationValue.key(
- fragments, BuildOptions.diffForReconstruction(defaultBuildOptions, options));
+ BuildConfigurationValue.keyWithPlatformMapping(
+ getPlatformMappingValue(eventHandler, options),
+ defaultBuildOptions,
+ fragments,
+ BuildOptions.diffForReconstruction(defaultBuildOptions, options));
BuildConfigurationValue result =
(BuildConfigurationValue)
evaluate(
@@ -2123,7 +2170,8 @@
@VisibleForTesting
@Nullable
public ConfiguredTarget getConfiguredTargetForTesting(
- ExtendedEventHandler eventHandler, Label label, BuildConfiguration configuration) {
+ ExtendedEventHandler eventHandler, Label label, BuildConfiguration configuration)
+ throws TransitionException, InvalidConfigurationException {
return getConfiguredTargetForTesting(eventHandler, label, configuration, NoTransition.INSTANCE);
}
@@ -2134,7 +2182,8 @@
ExtendedEventHandler eventHandler,
Label label,
BuildConfiguration configuration,
- ConfigurationTransition transition) {
+ ConfigurationTransition transition)
+ throws TransitionException, InvalidConfigurationException {
ConfiguredTargetAndData configuredTargetAndData =
getConfiguredTargetAndDataForTesting(eventHandler, label, configuration, transition);
return configuredTargetAndData == null ? null : configuredTargetAndData.getConfiguredTarget();
@@ -2146,7 +2195,8 @@
ExtendedEventHandler eventHandler,
Label label,
BuildConfiguration configuration,
- ConfigurationTransition transition) {
+ ConfigurationTransition transition)
+ throws TransitionException, InvalidConfigurationException {
return Iterables.getFirst(
getConfiguredTargetsForTesting(
eventHandler,
@@ -2162,7 +2212,8 @@
@VisibleForTesting
@Nullable
public ConfiguredTargetAndData getConfiguredTargetAndDataForTesting(
- ExtendedEventHandler eventHandler, Label label, BuildConfiguration configuration) {
+ ExtendedEventHandler eventHandler, Label label, BuildConfiguration configuration)
+ throws TransitionException, InvalidConfigurationException {
return getConfiguredTargetAndDataForTesting(
eventHandler, label, configuration, NoTransition.INSTANCE);
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java
index 745c637..5ef6c9f 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java
@@ -44,7 +44,9 @@
import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory;
+import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.configuredtargets.InputFileConfiguredTarget;
+import com.google.devtools.build.lib.analysis.skylark.StarlarkTransition;
import com.google.devtools.build.lib.buildtool.BuildRequestOptions;
import com.google.devtools.build.lib.clock.BlazeClock;
import com.google.devtools.build.lib.cmdline.Label;
@@ -449,7 +451,11 @@
} catch (LabelSyntaxException e) {
throw new AssertionError(e);
}
- return skyframeExecutor.getConfiguredTargetAndDataForTesting(reporter, parsedLabel, config);
+ try {
+ return skyframeExecutor.getConfiguredTargetAndDataForTesting(reporter, parsedLabel, config);
+ } catch (StarlarkTransition.TransitionException | InvalidConfigurationException e) {
+ throw new AssertionError(e);
+ }
}
protected Target getTarget(String label) throws InterruptedException {
@@ -494,8 +500,12 @@
} catch (LabelSyntaxException e) {
throw new AssertionError(e);
}
- return skyframeExecutor.getConfiguredTargetAndDataForTesting(
- reporter, parsedLabel, configuration);
+ try {
+ return skyframeExecutor.getConfiguredTargetAndDataForTesting(
+ reporter, parsedLabel, configuration);
+ } catch (StarlarkTransition.TransitionException | InvalidConfigurationException e) {
+ throw new AssertionError(e);
+ }
}
protected final BuildConfiguration getConfiguration(TransitiveInfoCollection ct) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewForTesting.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewForTesting.java
index 849b3502..c99c79a 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewForTesting.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewForTesting.java
@@ -54,6 +54,7 @@
import com.google.devtools.build.lib.analysis.config.TransitionResolver;
import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
+import com.google.devtools.build.lib.analysis.skylark.StarlarkTransition;
import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory;
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
@@ -188,7 +189,8 @@
*/
@VisibleForTesting
public BuildConfiguration getConfigurationForTesting(
- Target target, BuildConfiguration config, ExtendedEventHandler eventHandler) {
+ Target target, BuildConfiguration config, ExtendedEventHandler eventHandler)
+ throws StarlarkTransition.TransitionException, InvalidConfigurationException {
List<TargetAndConfiguration> node =
ImmutableList.<TargetAndConfiguration>of(new TargetAndConfiguration(target, config));
LinkedHashSet<TargetAndConfiguration> configs =
@@ -216,7 +218,7 @@
ConfiguredTarget ct,
BuildConfigurationCollection configurations)
throws EvalException, InvalidConfigurationException, InterruptedException,
- InconsistentAspectOrderException {
+ InconsistentAspectOrderException, StarlarkTransition.TransitionException {
return Collections2.transform(
getConfiguredTargetAndDataDirectPrerequisitesForTesting(eventHandler, ct, configurations),
ConfiguredTargetAndData::getConfiguredTarget);
@@ -224,24 +226,24 @@
// TODO(janakr): pass the configuration in as a parameter here and above.
private Collection<ConfiguredTargetAndData>
- getConfiguredTargetAndDataDirectPrerequisitesForTesting(
- ExtendedEventHandler eventHandler,
- ConfiguredTarget ct,
- BuildConfigurationCollection configurations)
- throws EvalException, InvalidConfigurationException, InterruptedException,
- InconsistentAspectOrderException {
+ getConfiguredTargetAndDataDirectPrerequisitesForTesting(
+ ExtendedEventHandler eventHandler,
+ ConfiguredTarget ct,
+ BuildConfigurationCollection configurations)
+ throws EvalException, InvalidConfigurationException, InterruptedException,
+ InconsistentAspectOrderException, StarlarkTransition.TransitionException {
return getConfiguredTargetAndDataDirectPrerequisitesForTesting(
eventHandler, ct, ct.getConfigurationKey(), configurations);
}
@VisibleForTesting
public Collection<ConfiguredTargetAndData>
- getConfiguredTargetAndDataDirectPrerequisitesForTesting(
- ExtendedEventHandler eventHandler,
- ConfiguredTargetAndData ct,
- BuildConfigurationCollection configurations)
- throws EvalException, InvalidConfigurationException, InterruptedException,
- InconsistentAspectOrderException {
+ getConfiguredTargetAndDataDirectPrerequisitesForTesting(
+ ExtendedEventHandler eventHandler,
+ ConfiguredTargetAndData ct,
+ BuildConfigurationCollection configurations)
+ throws EvalException, InvalidConfigurationException, InterruptedException,
+ InconsistentAspectOrderException, StarlarkTransition.TransitionException {
return getConfiguredTargetAndDataDirectPrerequisitesForTesting(
eventHandler,
ct.getConfiguredTarget(),
@@ -250,13 +252,13 @@
}
private Collection<ConfiguredTargetAndData>
- getConfiguredTargetAndDataDirectPrerequisitesForTesting(
- ExtendedEventHandler eventHandler,
- ConfiguredTarget ct,
- BuildConfigurationValue.Key configuration,
- BuildConfigurationCollection configurations)
- throws EvalException, InvalidConfigurationException, InterruptedException,
- InconsistentAspectOrderException {
+ getConfiguredTargetAndDataDirectPrerequisitesForTesting(
+ ExtendedEventHandler eventHandler,
+ ConfiguredTarget ct,
+ BuildConfigurationValue.Key configuration,
+ BuildConfigurationCollection configurations)
+ throws EvalException, InvalidConfigurationException, InterruptedException,
+ InconsistentAspectOrderException, StarlarkTransition.TransitionException {
return skyframeExecutor.getConfiguredTargetsForTesting(
eventHandler,
configuration,
@@ -272,7 +274,8 @@
final ConfiguredTarget ct,
BuildConfigurationCollection configurations,
ImmutableSet<Label> toolchainLabels)
- throws EvalException, InterruptedException, InconsistentAspectOrderException {
+ throws EvalException, InterruptedException, InconsistentAspectOrderException,
+ StarlarkTransition.TransitionException, InvalidConfigurationException {
Target target = null;
try {
@@ -336,7 +339,8 @@
* present in this rule's attributes.
*/
private ImmutableMap<Label, ConfigMatchingProvider> getConfigurableAttributeKeysForTesting(
- ExtendedEventHandler eventHandler, TargetAndConfiguration ctg) {
+ ExtendedEventHandler eventHandler, TargetAndConfiguration ctg)
+ throws StarlarkTransition.TransitionException, InvalidConfigurationException {
if (!(ctg.getTarget() instanceof Rule)) {
return ImmutableMap.of();
}
@@ -362,7 +366,7 @@
BuildConfigurationCollection configurations,
ImmutableSet<Label> toolchainLabels)
throws EvalException, InvalidConfigurationException, InterruptedException,
- InconsistentAspectOrderException {
+ InconsistentAspectOrderException, StarlarkTransition.TransitionException {
OrderedSetMultimap<DependencyKind, Dependency> depNodeNames =
getDirectPrerequisiteDependenciesForTesting(
eventHandler, target, configurations, toolchainLabels);
@@ -412,7 +416,8 @@
*/
@VisibleForTesting
public ConfiguredTarget getConfiguredTargetForTesting(
- ExtendedEventHandler eventHandler, Label label, BuildConfiguration config) {
+ ExtendedEventHandler eventHandler, Label label, BuildConfiguration config)
+ throws StarlarkTransition.TransitionException, InvalidConfigurationException {
ConfigurationTransition transition =
getTopLevelTransitionForTarget(label, config, eventHandler);
if (transition == null) {
@@ -423,15 +428,15 @@
@VisibleForTesting
public ConfiguredTargetAndData getConfiguredTargetAndDataForTesting(
- ExtendedEventHandler eventHandler, Label label, BuildConfiguration config) {
+ ExtendedEventHandler eventHandler, Label label, BuildConfiguration config)
+ throws StarlarkTransition.TransitionException, InvalidConfigurationException {
ConfigurationTransition transition =
getTopLevelTransitionForTarget(label, config, eventHandler);
if (transition == null) {
return null;
}
- return skyframeExecutor.getConfiguredTargetAndDataForTesting(
- eventHandler, label, config, transition);
-
+ return skyframeExecutor.getConfiguredTargetAndDataForTesting(
+ eventHandler, label, config, transition);
}
/**
@@ -443,7 +448,8 @@
StoredEventHandler eventHandler,
BuildConfigurationCollection configurations)
throws EvalException, InvalidConfigurationException, InterruptedException,
- InconsistentAspectOrderException, ToolchainException {
+ InconsistentAspectOrderException, ToolchainException,
+ StarlarkTransition.TransitionException {
BuildConfiguration targetConfig =
skyframeExecutor.getConfiguration(eventHandler, target.getConfigurationKey());
CachingAnalysisEnvironment env =
@@ -470,7 +476,8 @@
AnalysisEnvironment env,
BuildConfigurationCollection configurations)
throws EvalException, InvalidConfigurationException, InterruptedException,
- InconsistentAspectOrderException, ToolchainException {
+ InconsistentAspectOrderException, ToolchainException,
+ StarlarkTransition.TransitionException {
BuildConfiguration targetConfig =
skyframeExecutor.getConfiguration(eventHandler, configuredTarget.getConfigurationKey());
Target target = null;
@@ -538,7 +545,7 @@
Label desiredTarget,
BuildConfigurationCollection configurations)
throws EvalException, InvalidConfigurationException, InterruptedException,
- InconsistentAspectOrderException {
+ InconsistentAspectOrderException, StarlarkTransition.TransitionException {
Collection<ConfiguredTargetAndData> configuredTargets =
getPrerequisiteMapForTesting(
eventHandler,
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 58fa36d..a8ee477 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -85,12 +85,14 @@
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Options.ConfigsMode;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
+import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NullTransition;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.configuredtargets.FileConfiguredTarget;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.analysis.extra.ExtraAction;
+import com.google.devtools.build.lib.analysis.skylark.StarlarkTransition;
import com.google.devtools.build.lib.analysis.test.BaselineCoverageAction;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
import com.google.devtools.build.lib.buildtool.BuildRequestOptions;
@@ -872,16 +874,24 @@
* may return null. In that case, use a debugger to inspect the {@link ErrorInfo} for the
* evaluation, which is produced by the {@link MemoizingEvaluator#getExistingValue} call in {@link
* SkyframeExecutor#getConfiguredTargetForTesting}. See also b/26382502.
+ *
+ * @throws AssertionError if the target cannot be transitioned into with the given configuration
*/
protected ConfiguredTarget getConfiguredTarget(Label label, BuildConfiguration config) {
- return view.getConfiguredTargetForTesting(reporter, BlazeTestUtils.convertLabel(label), config);
+ try {
+ return view.getConfiguredTargetForTesting(
+ reporter, BlazeTestUtils.convertLabel(label), config);
+ } catch (InvalidConfigurationException | StarlarkTransition.TransitionException e) {
+ throw new AssertionError(e);
+ }
}
/**
* Returns a ConfiguredTargetAndData for the specified label, using the given build configuration.
*/
protected ConfiguredTargetAndData getConfiguredTargetAndData(
- Label label, BuildConfiguration config) {
+ Label label, BuildConfiguration config)
+ throws StarlarkTransition.TransitionException, InvalidConfigurationException {
return view.getConfiguredTargetAndDataForTesting(reporter, label, config);
}
@@ -891,7 +901,8 @@
* config in the ConfiguredTargetAndData's ConfiguredTarget.
*/
public ConfiguredTargetAndData getConfiguredTargetAndData(String label)
- throws LabelSyntaxException {
+ throws LabelSyntaxException, StarlarkTransition.TransitionException,
+ InvalidConfigurationException {
return getConfiguredTargetAndData(Label.parseAbsolute(label, ImmutableMap.of()), targetConfig);
}
@@ -1714,16 +1725,22 @@
/**
* Returns the configuration created by applying the given transition to the source configuration.
+ *
+ * @throws AssertionError if the transition couldn't be evaluated
*/
- protected BuildConfiguration getConfiguration(BuildConfiguration fromConfig,
- PatchTransition transition) throws InterruptedException {
+ protected BuildConfiguration getConfiguration(
+ BuildConfiguration fromConfig, PatchTransition transition) throws InterruptedException {
if (transition == NoTransition.INSTANCE) {
return fromConfig;
} else if (transition == NullTransition.INSTANCE) {
return null;
} else {
- return skyframeExecutor.getConfigurationForTesting(
- reporter, fromConfig.fragmentClasses(), transition.patch(fromConfig.getOptions()));
+ try {
+ return skyframeExecutor.getConfigurationForTesting(
+ reporter, fromConfig.fragmentClasses(), transition.patch(fromConfig.getOptions()));
+ } catch (OptionsParsingException | InvalidConfigurationException e) {
+ throw new AssertionError(e);
+ }
}
}
@@ -1750,7 +1767,9 @@
ConfiguredTargetAndData ctad;
try {
ctad = getConfiguredTargetAndData(ct.getLabel().toString());
- } catch (LabelSyntaxException e) {
+ } catch (LabelSyntaxException
+ | StarlarkTransition.TransitionException
+ | InvalidConfigurationException e) {
throw new RuntimeException(e);
}
return getMapperFromConfiguredTargetAndTarget(ctad);
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
index 28e7052..58d5e72 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
@@ -42,6 +42,7 @@
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
+import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.analysis.util.ScratchAttributeWriter;
@@ -59,6 +60,7 @@
import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.common.options.OptionsParsingException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -299,8 +301,9 @@
* Returns all child configurations resulting from a given split transition on a given
* configuration.
*/
- protected List<BuildConfiguration> getSplitConfigurations(BuildConfiguration configuration,
- SplitTransition splitTransition) throws InterruptedException {
+ protected List<BuildConfiguration> getSplitConfigurations(
+ BuildConfiguration configuration, SplitTransition splitTransition)
+ throws InterruptedException, OptionsParsingException, InvalidConfigurationException {
ImmutableList.Builder<BuildConfiguration> splitConfigs = ImmutableList.builder();
for (BuildOptions splitOptions : splitTransition.split(configuration.getOptions())) {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/platform/PlatformConfigurationApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/platform/PlatformConfigurationApiTest.java
index f35776c..34437c6 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/platform/PlatformConfigurationApiTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/platform/PlatformConfigurationApiTest.java
@@ -74,33 +74,6 @@
}
@Test
- public void testTargetPlatform_multiple() throws Exception {
- scratch.file(
- "platforms/BUILD",
- "platform(name = 'test_platform1')",
- "platform(name = 'test_platform2')");
-
- useConfiguration("--platforms=//platforms:test_platform1,//platforms:test_platform2");
- ruleBuilder().build();
- scratch.file(
- "foo/BUILD",
- "load(':extension.bzl', 'my_rule')",
- "my_rule(",
- " name = 'my_skylark_rule',",
- ")");
- assertNoEvents();
-
- PlatformConfigurationApi platformConfiguration = fetchPlatformConfiguration();
- assertThat(platformConfiguration).isNotNull();
- // Despite setting two platforms in the flag, only a single platform should be visible to the
- // target.
- assertThat(platformConfiguration.getTargetPlatform())
- .isEqualTo(Label.parseAbsoluteUnchecked("//platforms:test_platform1"));
- assertThat(platformConfiguration.getTargetPlatforms())
- .containsExactly(Label.parseAbsoluteUnchecked("//platforms:test_platform1"));
- }
-
- @Test
public void testEnabledToolchainTypes() throws Exception {
scratch.file(
"toolchains/BUILD",
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PlatformMappingFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PlatformMappingFunctionTest.java
index 5a0867e..c5a962b 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PlatformMappingFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PlatformMappingFunctionTest.java
@@ -83,7 +83,7 @@
executeFunction(PlatformMappingValue.Key.create(null));
BuildConfigurationValue.Key key =
- BuildConfigurationValue.key(PLATFORM_FRAGMENT_CLASS, EMPTY_DIFF);
+ BuildConfigurationValue.keyWithoutPlatformMapping(PLATFORM_FRAGMENT_CLASS, EMPTY_DIFF);
BuildConfigurationValue.Key mapped =
platformMappingValue.map(key, DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS);
@@ -155,6 +155,6 @@
BuildOptions.OptionsDiffForReconstruction diff =
BuildOptions.diffForReconstruction(DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS, modifiedOptions);
- return BuildConfigurationValue.key(PLATFORM_FRAGMENT_CLASS, diff);
+ return BuildConfigurationValue.keyWithoutPlatformMapping(PLATFORM_FRAGMENT_CLASS, diff);
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PlatformMappingValueTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PlatformMappingValueTest.java
index af8c114..39a2e04 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PlatformMappingValueTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PlatformMappingValueTest.java
@@ -65,7 +65,7 @@
new PlatformMappingValue(ImmutableMap.of(), ImmutableMap.of());
BuildConfigurationValue.Key key =
- BuildConfigurationValue.key(PLATFORM_FRAGMENT_CLASS, EMPTY_DIFF);
+ BuildConfigurationValue.keyWithoutPlatformMapping(PLATFORM_FRAGMENT_CLASS, EMPTY_DIFF);
BuildConfigurationValue.Key mapped =
mappingValue.map(key, DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS);
@@ -238,6 +238,6 @@
BuildOptions.OptionsDiffForReconstruction diff =
BuildOptions.diffForReconstruction(DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS, modifiedOptions);
- return BuildConfigurationValue.key(PLATFORM_FRAGMENT_CLASS, diff);
+ return BuildConfigurationValue.keyWithoutPlatformMapping(PLATFORM_FRAGMENT_CLASS, diff);
}
}
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index 94c7075..2df2986 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -880,3 +880,10 @@
data = [":test-deps"],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
+
+sh_test(
+ name = "platform_mapping_test",
+ srcs = ["platform_mapping_test.sh"],
+ data = [":test-deps"],
+ tags = ["no_windows"],
+)
diff --git a/src/test/shell/bazel/platform_mapping_test.sh b/src/test/shell/bazel/platform_mapping_test.sh
new file mode 100755
index 0000000..9be52af
--- /dev/null
+++ b/src/test/shell/bazel/platform_mapping_test.sh
@@ -0,0 +1,195 @@
+#!/bin/bash
+#
+# Copyright 2017 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Test the providers and rules related to toolchains.
+#
+
+# Load the test setup defined in the parent directory
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${CURRENT_DIR}/../integration_test_setup.sh" \
+ || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
+
+function set_up() {
+ create_new_workspace
+
+ mkdir package
+
+ # Create shared platform definitions
+ mkdir plat
+ cat > plat/BUILD <<EOF
+platform(
+ name = 'platform1',
+ constraint_values = [])
+
+platform(
+ name = 'platform2',
+ constraint_values = [])
+EOF
+
+ # Create shared report rule for printing flag and platform info.
+ mkdir report
+ touch report/BUILD
+ cat > report/report.bzl <<EOF
+def _report_impl(ctx):
+ print('copts: %s' % ctx.fragments.cpp.copts)
+ print('platform: %s' % ctx.fragments.platform.platform)
+
+report_flags = rule(
+ implementation = _report_impl,
+ attrs = {},
+ fragments = ["cpp", "platform"]
+)
+EOF
+}
+
+function test_top_level_flags_to_platform_mapping() {
+ cat > platform_mappings <<EOF
+flags:
+ --cpu=arm64
+ //plat:platform1
+EOF
+
+ cat > package/BUILD <<EOF
+load("//report:report.bzl", "report_flags")
+report_flags(name = "report")
+EOF
+
+ bazel build --cpu=arm64 package:report &> $TEST_log \
+ || fail "Build failed unexpectedly"
+ expect_log "platform: //plat:platform1"
+}
+
+function test_top_level_platform_to_flags_mapping() {
+ cat > platform_mappings <<EOF
+platforms:
+ //plat:platform1
+ --copt=foo
+EOF
+
+ cat > package/BUILD <<EOF
+load("//report:report.bzl", "report_flags")
+report_flags(name = "report")
+EOF
+
+ bazel build --platforms=//plat:platform1 package:report &> $TEST_log \
+ || fail "Build failed unexpectedly"
+ expect_log "copts: \[\"foo\"\]"
+}
+
+function test_custom_platform_mapping_location() {
+ mkdir custom
+ cat > custom/platform_mappings <<EOF
+flags:
+ --cpu=arm64
+ //plat:platform1
+EOF
+
+ cat > package/BUILD <<EOF
+load("//report:report.bzl", "report_flags")
+report_flags(name = "report")
+EOF
+
+ bazel build --cpu=arm64 --platform_mappings=custom/platform_mappings \
+ package:report &> $TEST_log || fail "Build failed unexpectedly"
+ expect_log "platform: //plat:platform1"
+}
+
+function test_top_level_multi_platform_mapping() {
+ cat > platform_mappings <<EOF
+flags:
+ --cpu=k8
+ //plat:platform1
+ --cpu=arm64
+ //plat:platform2
+EOF
+
+ cat > package/BUILD <<EOF
+load("//report:report.bzl", "report_flags")
+report_flags(name = "report")
+EOF
+
+ bazel build --experimental_multi_cpu=k8,arm64 package:report &> $TEST_log \
+ || fail "Build failed unexpectedly"
+ expect_log "platform: //plat:platform1"
+ expect_log "platform: //plat:platform2"
+}
+
+function test_transition_platform_mapping() {
+ cat > platform_mappings <<EOF
+flags:
+ --cpu=k8
+ //plat:platform1
+ --cpu=arm64
+ //plat:platform2
+EOF
+
+ cat > package/rule.bzl <<EOF
+def _my_transition_impl(settings, attrs):
+ return {
+ "//command_line_option:cpu": "arm64",
+ "//command_line_option:copt": ["foo"],
+ # Platforms *must* be wiped for transitions to correctly participate in
+ # platform mapping.
+ "//command_line_option:platforms": [],
+ }
+
+
+my_transition = transition(
+ implementation = _my_transition_impl,
+ inputs = [],
+ outputs = [
+ "//command_line_option:cpu",
+ "//command_line_option:copt",
+ "//command_line_option:platforms",
+ ],
+)
+
+
+def _my_rule_impl(ctx):
+ return []
+
+
+my_rule = rule(
+ implementation = _my_rule_impl,
+ attrs = {
+ "deps": attr.label_list(cfg = my_transition),
+ "_whitelist_function_transition": attr.label(
+ default = "@//tools/whitelists/function_transition_whitelist"),
+ }
+)
+EOF
+
+ cat > package/BUILD <<EOF
+load("//report:report.bzl", "report_flags")
+load("//package:rule.bzl", "my_rule")
+
+my_rule(
+ name = "custom",
+ deps = [ ":report" ]
+)
+
+report_flags(name = "report")
+EOF
+
+ bazel build --cpu=k8 package:custom \
+ --experimental_starlark_config_transitions &> $TEST_log \
+ || fail "Build failed unexpectedly"
+ expect_not_log "platform: //plat:platform1"
+ expect_log "platform: //plat:platform2"
+}
+
+run_suite "platform mapping test"
+