diff options
author | 2017-01-11 23:37:05 +0000 | |
---|---|---|
committer | 2017-01-12 09:12:04 +0000 | |
commit | 19dda2577ece84e99f82af41c18a7bd2c796ff99 (patch) | |
tree | f97f3e744d3ee1af3653175a921f941177e342c0 /src/main/java/com | |
parent | f2ad3c2a017fc7b643744074ca16053a35533a30 (diff) |
Allows a rule class to specify a configuration transtion that will apply to all
incoming edges if dynamic configurations are turned on.
This CL does not cover top-level nodes.
--
PiperOrigin-RevId: 144258789
MOS_MIGRATED_REVID=144258789
Diffstat (limited to 'src/main/java/com')
3 files changed, 120 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java index c80b2b463a..553c88c9db 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.analysis.config; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.base.Verify; @@ -46,6 +47,7 @@ import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.packages.AspectDescriptor; import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; import com.google.devtools.build.lib.packages.Attribute.Configurator; import com.google.devtools.build.lib.packages.Attribute.SplitTransition; import com.google.devtools.build.lib.packages.Attribute.Transition; @@ -1797,11 +1799,22 @@ public final class BuildConfiguration { } getCurrentTransitions().configurationHook(fromRule, attribute, toTarget, this); + Rule associatedRule = toTarget.getAssociatedRule(); + PatchTransition ruleClassTransition = (PatchTransition) + associatedRule.getRuleClassObject().getTransition(); + + if (ruleClassTransition != null) { + if (currentTransition == ConfigurationTransition.NONE) { + currentTransition = ruleClassTransition; + } else { + currentTransition = new ComposingSplitTransition(ruleClassTransition, currentTransition); + } + } + // We don't support rule class configurators (which might imply composed transitions). // The only current use of that is LIPO, which can't currently be invoked with dynamic // configurations (e.g. this code can never get called for LIPO builds). So check that // if there is a configurator, it's for LIPO, in which case we can ignore it. - Rule associatedRule = toTarget.getAssociatedRule(); if (associatedRule != null) { @SuppressWarnings("unchecked") RuleClass.Configurator<?, ?> func = @@ -2387,6 +2400,11 @@ public final class BuildConfiguration { return options.cpu; } + @VisibleForTesting + public String getHostCpu() { + return options.hostCpu; + } + public boolean runfilesEnabled() { switch (options.enableRunfiles) { case YES: diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java new file mode 100644 index 0000000000..c4287d8ea9 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java @@ -0,0 +1,66 @@ +// 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. + +package com.google.devtools.build.lib.analysis.config; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; +import com.google.devtools.build.lib.packages.Attribute.SplitTransition; +import com.google.devtools.build.lib.packages.Attribute.Transition; +import java.util.List; + +/** + * A split transition that combines a Transition with a {@link PatchTransition}. The patch is + * applied first, followed by the Transition. + * + * <p>We implement a {@link SplitTransition} here since that abstraction can capture all possible + * composed transitions - both those that produce multiple output configurations and those that + * do not. + */ +public class ComposingSplitTransition implements SplitTransition<BuildOptions> { + + private PatchTransition patch; + private Transition transition; + + /** + * Creates a {@link ComposingSplitTransition} with the given {@link Transition} and + * {@link PatchTransition}. + */ + public ComposingSplitTransition(PatchTransition patch, Transition transition) { + this.patch = patch; + this.transition = transition; + } + + @Override + public List<BuildOptions> split(BuildOptions buildOptions) { + BuildOptions patchedOptions = patch.apply(buildOptions); + if (transition == ConfigurationTransition.NONE) { + return ImmutableList.<BuildOptions>of(patchedOptions); + } else if (transition instanceof PatchTransition) { + return ImmutableList.<BuildOptions>of(((PatchTransition) transition).apply(patchedOptions)); + } else if (transition instanceof SplitTransition) { + return ((SplitTransition<BuildOptions>) transition).split(patchedOptions); + } else { + throw new IllegalStateException( + String.format("Unsupported composite transition type: %s", + transition.getClass().getName())); + } + } + + @Override + public boolean defaultsToSelf() { + return true; + } +} + diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java index b6b314bbcf..5bd4d83f60 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java @@ -36,6 +36,7 @@ import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.events.NullEventHandler; import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate; import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate.CannotPrecomputeDefaultsException; +import com.google.devtools.build.lib.packages.Attribute.Transition; import com.google.devtools.build.lib.packages.BuildType.SelectorList; import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy; import com.google.devtools.build.lib.packages.RuleFactory.AttributeValuesMap; @@ -473,6 +474,7 @@ public final class RuleClass { private boolean outputsDefaultExecutable = false; private ImplicitOutputsFunction implicitOutputsFunction = ImplicitOutputsFunction.NONE; private Configurator<?, ?> configurator = NO_CHANGE; + private Transition transition; private ConfiguredTargetFactory<?, ?> configuredTargetFactory = null; private PredicateWithMessage<Rule> validityPredicate = PredicatesWithMessage.<Rule>alwaysTrue(); @@ -586,6 +588,7 @@ public final class RuleClass { outputsDefaultExecutable, implicitOutputsFunction, configurator, + transition, configuredTargetFactory, validityPredicate, preferredDependencyPredicate, @@ -719,10 +722,28 @@ public final class RuleClass { public Builder cfg(Configurator<?, ?> configurator) { Preconditions.checkState(type != RuleClassType.ABSTRACT, "Setting not inherited property (cfg) of abstract rule class '%s'", name); + Preconditions.checkState(transition == null, + "Property cfg cannot be set to both a configurator and a transition"); this.configurator = configurator; return this; } + /** + * Applies the given transition to all incoming edges for this rule class. Does not work with + * static configurations. + * + * <p>Note that the given transition must be a PatchTransition instance. We use the more + * general Transtion here because PatchTransition is not available in this package. + */ + public Builder cfg(Transition transition) { + Preconditions.checkState(type != RuleClassType.ABSTRACT, + "Setting not inherited property (cfg) of abstract rule class '%s'", name); + Preconditions.checkState(configurator == NO_CHANGE, + "Property cfg cannot be set to both a configurator and a transition"); + this.transition = transition; + return this; + } + public Builder factory(ConfiguredTargetFactory<?, ?> factory) { this.configuredTargetFactory = factory; return this; @@ -983,6 +1004,14 @@ public final class RuleClass { private final Configurator<?, ?> configurator; /** + * A configuration transition that should be applied on any edge of the configured target graph + * that leads into a target of this rule class. + * + * <p>This transition must be a PatchTransition, but that class is not accessible in this package. + */ + private final Transition transition; + + /** * The factory that creates configured targets from this rule. */ private final ConfiguredTargetFactory<?, ?> configuredTargetFactory; @@ -1065,6 +1094,7 @@ public final class RuleClass { boolean outputsDefaultExecutable, ImplicitOutputsFunction implicitOutputsFunction, Configurator<?, ?> configurator, + Transition transition, ConfiguredTargetFactory<?, ?> configuredTargetFactory, PredicateWithMessage<Rule> validityPredicate, Predicate<String> preferredDependencyPredicate, @@ -1086,6 +1116,7 @@ public final class RuleClass { this.binaryOutput = binaryOutput; this.implicitOutputsFunction = implicitOutputsFunction; this.configurator = Preconditions.checkNotNull(configurator); + this.transition = transition; this.configuredTargetFactory = configuredTargetFactory; this.validityPredicate = validityPredicate; this.preferredDependencyPredicate = preferredDependencyPredicate; @@ -1155,6 +1186,10 @@ public final class RuleClass { return (Configurator<C, R>) configurator; } + public Transition getTransition() { + return transition; + } + @SuppressWarnings("unchecked") public <CT, RC> ConfiguredTargetFactory<CT, RC> getConfiguredTargetFactory() { return (ConfiguredTargetFactory<CT, RC>) configuredTargetFactory; |