aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
authorGravatar Cal Peyser <cpeyser@google.com>2017-01-11 23:37:05 +0000
committerGravatar Marcel Hlopko <hlopko@google.com>2017-01-12 09:12:04 +0000
commit19dda2577ece84e99f82af41c18a7bd2c796ff99 (patch)
treef97f3e744d3ee1af3653175a921f941177e342c0 /src/main/java/com/google/devtools
parentf2ad3c2a017fc7b643744074ca16053a35533a30 (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/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java66
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleClass.java35
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;