aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD1
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java49
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java44
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/DefaultsPackage.java72
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidRuleClasses.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java67
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java17
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/Attribute.java278
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java21
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java37
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java34
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java58
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java21
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java41
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java181
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java25
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java37
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java181
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java11
27 files changed, 583 insertions, 685 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index ddadda214f..6bc24fa7fc 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -513,6 +513,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/buildeventstream",
"//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
+ "//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/collect",
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
"//src/main/java/com/google/devtools/build/lib/concurrent",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
index f52d66f209..8a8e815ad2 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
@@ -40,11 +40,9 @@ import com.google.devtools.build.lib.analysis.constraints.EnvironmentRule;
import com.google.devtools.build.lib.analysis.test.TestConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabelList;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.Attribute.Transition;
import com.google.devtools.build.lib.packages.AttributeMap;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
@@ -73,35 +71,32 @@ public class BaseRuleClasses {
}
};
+ // TODO(b/65746853): provide a way to do this without passing the entire configuration
/**
* Implementation for the :action_listener attribute.
+ *
+ * <p>action_listeners are special rules; they tell the build system to add extra_actions to
+ * existing rules. As such they need an edge to every ConfiguredTarget with the limitation that
+ * they only run on the target configuration and should not operate on action_listeners and
+ * extra_actions themselves (to avoid cycles).
*/
@VisibleForTesting
- static final LateBoundLabelList<BuildConfiguration> ACTION_LISTENER =
- new LateBoundLabelList<BuildConfiguration>() {
- @Override
- public List<Label> resolve(Rule rule, AttributeMap attributes,
- BuildConfiguration configuration) {
- // action_listeners are special rules; they tell the build system to add extra_actions to
- // existing rules. As such they need an edge to every ConfiguredTarget with the limitation
- // that they only run on the target configuration and should not operate on action_listeners
- // and extra_actions themselves (to avoid cycles).
- return configuration.getActionListeners();
- }
- };
+ static final LateBoundDefault<?, List<Label>> ACTION_LISTENER =
+ LateBoundDefault.fromTargetConfiguration(
+ BuildConfiguration.class,
+ ImmutableList.of(),
+ (rule, attributes, configuration) -> configuration.getActionListeners());
- /**
- * Implementation for the :run_under attribute.
- */
- public static final LateBoundLabel<BuildConfiguration> RUN_UNDER =
- new LateBoundLabel<BuildConfiguration>() {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes,
- BuildConfiguration configuration) {
- RunUnder runUnder = configuration.getRunUnder();
- return runUnder == null ? null : runUnder.getLabel();
- }
- };
+ // TODO(b/65746853): provide a way to do this without passing the entire configuration
+ /** Implementation for the :run_under attribute. */
+ public static final LateBoundDefault<?, Label> RUN_UNDER =
+ LateBoundDefault.fromTargetConfiguration(
+ BuildConfiguration.class,
+ null,
+ (rule, attributes, configuration) -> {
+ RunUnder runUnder = configuration.getRunUnder();
+ return runUnder != null ? runUnder.getLabel() : null;
+ });
/**
* A base rule for all test rules.
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
index 4997a895f8..855c985486 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.analysis;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -367,9 +368,7 @@ public abstract class DependencyResolver {
continue;
}
- @SuppressWarnings("unchecked")
- LateBoundDefault<BuildConfiguration> lateBoundDefault =
- (LateBoundDefault<BuildConfiguration>) attribute.getLateBoundDefault();
+ LateBoundDefault<?, ?> lateBoundDefault = attribute.getLateBoundDefault();
Collection<BuildOptions> splitOptions =
getSplitOptions(depResolver.rule, attribute, ruleConfig);
@@ -452,20 +451,8 @@ public abstract class DependencyResolver {
throws EvalException, InterruptedException {
Preconditions.checkArgument(attribute.isLateBound());
- @SuppressWarnings("unchecked")
- LateBoundDefault<BuildConfiguration> lateBoundDefault =
- (LateBoundDefault<BuildConfiguration>) attribute.getLateBoundDefault();
-
- // TODO(bazel-team): This might be too expensive - can we cache this somehow?
- if (!lateBoundDefault.getRequiredConfigurationFragments().isEmpty()) {
- if (!config.hasAllFragments(lateBoundDefault.getRequiredConfigurationFragments())) {
- return ImmutableList.<Label>of();
- }
- }
-
- // TODO(bazel-team): We should check if the implementation tries to access an undeclared
- // fragment.
- Object actualValue = lateBoundDefault.resolve(rule, attributeMap, config);
+ Object actualValue =
+ resolveLateBoundDefault(attribute.getLateBoundDefault(), rule, attributeMap, config);
if (EvalUtils.isNullOrNone(actualValue)) {
return ImmutableList.<Label>of();
}
@@ -495,6 +482,29 @@ public abstract class DependencyResolver {
}
}
+ @VisibleForTesting(/* used to test LateBoundDefaults' default values */ )
+ public static <FragmentT, ValueT> ValueT resolveLateBoundDefault(
+ LateBoundDefault<FragmentT, ValueT> lateBoundDefault,
+ Rule rule,
+ AttributeMap attributeMap,
+ BuildConfiguration config) {
+ Class<FragmentT> fragmentClass = lateBoundDefault.getFragmentClass();
+ // TODO(b/65746853): remove this when nothing uses it anymore
+ if (BuildConfiguration.class.equals(fragmentClass)) {
+ return lateBoundDefault.resolve(rule, attributeMap, fragmentClass.cast(config));
+ }
+ if (Void.class.equals(fragmentClass)) {
+ return lateBoundDefault.resolve(rule, attributeMap, null);
+ }
+ FragmentT fragment =
+ fragmentClass.cast(
+ config.getFragment((Class<? extends BuildConfiguration.Fragment>) fragmentClass));
+ if (fragment == null) {
+ return null;
+ }
+ return lateBoundDefault.resolve(rule, attributeMap, fragment);
+ }
+
/**
* Adds new dependencies to the given rule under the given attribute name
*
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/DefaultsPackage.java b/src/main/java/com/google/devtools/build/lib/analysis/config/DefaultsPackage.java
index 8ddadf130f..07d8c755b6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/DefaultsPackage.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/DefaultsPackage.java
@@ -21,7 +21,6 @@ import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
import com.google.devtools.build.lib.util.Preconditions;
-
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -29,52 +28,41 @@ import java.util.Set;
/**
* A helper class to compute and inject a defaults package into the package cache.
*
- * <p>The <code>//tools/defaults</code> package provides a mechanism let tool locations be
- * specified over the commandline, without requiring any special support in the rule code.
- * As such, it can be used in genrule <code>$(location)</code> substitutions.
+ * <p>The <code>//tools/defaults</code> package provides a mechanism let tool locations be specified
+ * over the commandline, without requiring any special support in the rule code. As such, it can be
+ * used in genrule <code>$(location)</code> substitutions.
*
* <p>It works as follows:
- * <ul>
- *
- * <li> SomeLanguage.createCompileAction will refer to a host-configured target for the
- * compiler by looking for
- * <code>env.getHostPrerequisiteArtifact("$somelanguage_compiler")</code>.
- *
- * <li> the attribute <code>$somelanguage_compiler</code> is defined in the
- * {@link RuleDefinition} subclass for that language.
- *
- * <li> if the attribute cannot be set on the command-line, its value may be a normal label.
- *
- * <li> if the attribute can be set on the command-line, its value will be
- * <code>//tools/defaults:somelanguage_compiler</code>.
- *
- * <li> in the latter case, the {@link BuildConfiguration.Fragment} subclass will define the
- * option (with an existing target, eg. <code>//third_party/somelanguage:compiler</code>), and
- * return the name in its implementation of {@link FragmentOptions#getDefaultsLabels}.
- *
- * <li> On startup, the rule is wired up with <code>//tools/defaults:somelanguage_compiler</code>.
- *
- * <li> On starting a build, the <code>//tools/defaults</code> package is synthesized, using
- * the values as specified on the command-line. The contents of
- * <code>tools/defaults/BUILD</code> is ignored.
- *
- * <li> Hence, changes in the command line values for tools are now handled exactly as if they
- * were changes in a BUILD file.
- *
- * <li> The file <code>tools/defaults/BUILD</code> must exist, so we create a package in that
- * location.
- *
- * <li> The code in {@link DefaultsPackage} can dump the synthesized package as a BUILD file,
- * so external tooling does not need to understand the intricacies of handling command-line
- * options.
*
+ * <ul>
+ * <li>SomeLanguage.createCompileAction will refer to a host-configured target for the compiler by
+ * looking for <code>env.getHostPrerequisiteArtifact("$somelanguage_compiler")</code>.
+ * <li>the attribute <code>$somelanguage_compiler</code> is defined in the {@link RuleDefinition}
+ * subclass for that language.
+ * <li>if the attribute cannot be set on the command-line, its value may be a normal label.
+ * <li>if the attribute can be set on the command-line, its value will be <code>
+ * //tools/defaults:somelanguage_compiler</code>.
+ * <li>in the latter case, the {@link BuildConfiguration.Fragment} subclass will define the option
+ * (with an existing target, eg. <code>//third_party/somelanguage:compiler</code>), and return
+ * the name in its implementation of {@link FragmentOptions#getDefaultsLabels}.
+ * <li>On startup, the rule is wired up with <code>//tools/defaults:somelanguage_compiler</code>.
+ * <li>On starting a build, the <code>//tools/defaults</code> package is synthesized, using the
+ * values as specified on the command-line. The contents of <code>tools/defaults/BUILD</code>
+ * is ignored.
+ * <li>Hence, changes in the command line values for tools are now handled exactly as if they were
+ * changes in a BUILD file.
+ * <li>The file <code>tools/defaults/BUILD</code> must exist, so we create a package in that
+ * location.
+ * <li>The code in {@link DefaultsPackage} can dump the synthesized package as a BUILD file, so
+ * external tooling does not need to understand the intricacies of handling command-line
+ * options.
* </ul>
*
- * <p>For built-in rules (as opposed to genrules), late-bound labels provide an alternative
- * method of depending on command-line values. These work by declaring attribute default values
- * to be {@link LateBoundLabel} instances, whose <code>resolve(Rule rule, AttributeMap attributes,
- * T configuration)</code> method will have access to {@link BuildConfiguration}, which in turn
- * may depend on command line flag values.
+ * <p>For built-in rules (as opposed to genrules), late-bound labels provide an alternative method
+ * of depending on command-line values. These work by declaring attribute default values to be
+ * {@link LateBoundDefault} instances, whose <code>resolve(Rule rule, AttributeMap attributes,
+ * FragmentT configuration)</code> method will have access to a {@link BuildConfiguration.Fragment},
+ * which in turn may depend on command line flag values.
*/
public final class DefaultsPackage {
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 21a5a31ffd..39f1dcbf93 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -74,7 +74,7 @@ import com.google.devtools.build.lib.bazel.rules.workspace.MavenServerRule;
import com.google.devtools.build.lib.bazel.rules.workspace.NewGitRepositoryRule;
import com.google.devtools.build.lib.bazel.rules.workspace.NewHttpArchiveRule;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.rules.Alias.AliasRule;
import com.google.devtools.build.lib.rules.android.AarImportBaseRule;
import com.google.devtools.build.lib.rules.android.AndroidBinaryOnlyRule;
@@ -464,8 +464,7 @@ public class BazelRuleClassProvider {
new RuleSet() {
@Override
public void init(Builder builder) {
- LateBoundLabel<BuildConfiguration> hostJdkAttribute =
- JavaSemantics.hostJdkAttribute(builder);
+ LateBoundDefault<?, Label> hostJdkAttribute = JavaSemantics.hostJdkAttribute(builder);
BazelJavaProtoAspect bazelJavaProtoAspect = new BazelJavaProtoAspect(hostJdkAttribute);
BazelJavaLiteProtoAspect bazelJavaLiteProtoAspect =
new BazelJavaLiteProtoAspect(hostJdkAttribute);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidRuleClasses.java
index ca5a6699dd..abc40e90ef 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidRuleClasses.java
@@ -16,13 +16,13 @@ package com.google.devtools.build.lib.bazel.rules.android;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+import static com.google.devtools.build.lib.rules.android.AndroidRuleClasses.getAndroidSdkLabel;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.rules.android.AndroidRuleClasses;
-import com.google.devtools.build.lib.rules.android.AndroidRuleClasses.AndroidSdkLabel;
import com.google.devtools.build.lib.rules.android.AndroidToolsDefaultsJar;
/** Rule class definitions for Android rules. */
@@ -37,8 +37,9 @@ public class BazelAndroidRuleClasses {
.add(
attr(":android_sdk", LABEL)
.allowedRuleClasses("android_sdk", "filegroup")
- .value(new AndroidSdkLabel(
- environment.getToolsLabel(AndroidRuleClasses.DEFAULT_SDK))))
+ .value(
+ getAndroidSdkLabel(
+ environment.getToolsLabel(AndroidRuleClasses.DEFAULT_SDK))))
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
index dc79061223..b5778480ab 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
@@ -42,15 +42,12 @@ import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.PlatformConfiguration;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
-import com.google.devtools.build.lib.packages.RawAttributeMapper;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
@@ -73,36 +70,30 @@ public class BazelCppRuleClasses {
static final SafeImplicitOutputsFunction CC_BINARY_IMPLICIT_OUTPUTS =
fromFunctions(CppRuleClasses.CC_BINARY_STRIPPED, CppRuleClasses.CC_BINARY_DEBUG_PACKAGE);
- public static final LateBoundLabel<BuildConfiguration> STL =
- new LateBoundLabel<BuildConfiguration>() {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes,
- BuildConfiguration configuration) {
- return getStl(rule, configuration);
- }
- };
-
/**
* Returns the STL prerequisite of the rule.
*
- * <p>If rule has an implicit $stl_default attribute returns STL version set on the
- * command line or if not set, the value of the $stl_default attribute. Returns
- * {@code null} otherwise.
+ * <p>If rule has an implicit $stl_default attribute returns STL version set on the command line
+ * or if not set, the value of the $stl_default attribute. Returns {@code null} otherwise.
*/
- private static Label getStl(Rule rule, BuildConfiguration original) {
- Label stl = null;
- if (rule.getRuleClassObject().hasAttr("$stl_default", BuildType.LABEL)) {
- Label stlConfigLabel = original.getFragment(CppConfiguration.class).getStl();
- Label stlRuleLabel = RawAttributeMapper.of(rule).get("$stl_default", BuildType.LABEL);
- if (stlConfigLabel == null) {
- stl = stlRuleLabel;
- } else if (!stlConfigLabel.equals(rule.getLabel()) && stlRuleLabel != null) {
- // prevents self-reference and a cycle through standard STL in the dependency graph
- stl = stlConfigLabel;
- }
- }
- return stl;
- }
+ public static final LateBoundDefault<?, Label> STL =
+ LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ null,
+ (rule, attributes, cppConfig) -> {
+ Label stl = null;
+ if (attributes.has("$stl_default", BuildType.LABEL)) {
+ Label stlConfigLabel = cppConfig.getStl();
+ Label stlRuleLabel = attributes.get("$stl_default", BuildType.LABEL);
+ if (stlConfigLabel == null) {
+ stl = stlRuleLabel;
+ } else if (!stlConfigLabel.equals(rule.getLabel()) && stlRuleLabel != null) {
+ // prevents self-reference and a cycle through standard STL in the dependency graph
+ stl = stlConfigLabel;
+ }
+ }
+ return stl;
+ });
static final FileTypeSet ALLOWED_SRC_FILES =
FileTypeSet.of(
@@ -421,14 +412,14 @@ public class BazelCppRuleClasses {
}
/** Implementation for the :lipo_context attribute. */
- static final LateBoundLabel<BuildConfiguration> LIPO_CONTEXT =
- new LateBoundLabel<BuildConfiguration>() {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- Label result = configuration.getFragment(CppConfiguration.class).getLipoContextLabel();
- return (rule == null || rule.getLabel().equals(result)) ? null : result;
- }
- };
+ static final LateBoundDefault<?, Label> LIPO_CONTEXT =
+ LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ null,
+ (rule, attributes, cppConfig) -> {
+ Label result = cppConfig.getLipoContextLabel();
+ return (rule == null || rule.getLabel().equals(result)) ? null : result;
+ });
/**
* Helper rule class.
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java
index 041956afe6..43139b40c5 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoAspect.java
@@ -14,9 +14,9 @@
package com.google.devtools.build.lib.bazel.rules.java.proto;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaSemantics;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.rules.java.proto.JavaLiteProtoAspect;
/** An Aspect which BazelJavaLiteProtoLibrary injects to build Java Lite protos. */
@@ -25,7 +25,7 @@ public class BazelJavaLiteProtoAspect extends JavaLiteProtoAspect {
public static final String DEFAULT_PROTO_TOOLCHAIN_LABEL =
"@com_google_protobuf_javalite//:javalite_toolchain";
- public BazelJavaLiteProtoAspect(LateBoundLabel<BuildConfiguration> hostJdkAttribute) {
+ public BazelJavaLiteProtoAspect(LateBoundDefault<?, Label> hostJdkAttribute) {
super(
BazelJavaSemantics.INSTANCE,
null /* jacocoLabel */,
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
index 9aed78a240..98f37d0fa8 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
@@ -20,13 +20,13 @@ import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaSemantics;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.rules.java.proto.JavaProtoAspect;
import com.google.devtools.build.lib.rules.java.proto.RpcSupport;
import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder;
@@ -35,7 +35,7 @@ import java.util.List;
/** An Aspect which BazelJavaProtoLibrary injects to build Java SPEED protos. */
public class BazelJavaProtoAspect extends JavaProtoAspect {
- public BazelJavaProtoAspect(LateBoundLabel<BuildConfiguration> hostJdkAttribute) {
+ public BazelJavaProtoAspect(LateBoundDefault<?, Label> hostJdkAttribute) {
super(
BazelJavaSemantics.INSTANCE,
null, /* jacocoAttr */
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java
index 006b82c660..dee60f9ba7 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java
@@ -26,12 +26,9 @@ import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.bazel.rules.cpp.BazelCppRuleClasses;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.packages.AttributeMap;
-import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.TriState;
@@ -46,13 +43,11 @@ import com.google.devtools.build.lib.util.FileType;
public final class BazelPyRuleClasses {
public static final FileType PYTHON_SOURCE = FileType.of(".py");
- public static final LateBoundLabel<BuildConfiguration> PY_INTERPRETER =
- new LateBoundLabel<BuildConfiguration>() {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(BazelPythonConfiguration.class).getPythonTop();
- }
- };
+ public static final LateBoundDefault<?, Label> PY_INTERPRETER =
+ LateBoundDefault.fromTargetConfiguration(
+ BazelPythonConfiguration.class,
+ null,
+ (rule, attributes, bazelPythonConfig) -> bazelPythonConfig.getPythonTop());
/**
* Base class for Python rule definitions.
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
index 5a020be02f..2fedb6a0b5 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
@@ -28,7 +28,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
-import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.Location;
@@ -676,9 +675,9 @@ public final class Attribute implements Comparable<Attribute> {
/**
* Sets the attribute default value to be late-bound, i.e., it is derived from the build
- * configuration.
+ * configuration and/or the rule's configured attributes.
*/
- public Builder<TYPE> value(LateBoundDefault<?> defaultValue) {
+ public Builder<TYPE> value(LateBoundDefault<?, ? extends TYPE> defaultValue) {
Preconditions.checkState(!valueSet, "the default value is already set");
Preconditions.checkState(name.isEmpty() || isLateBound(name));
value = defaultValue;
@@ -1549,137 +1548,204 @@ public final class Attribute implements Comparable<Attribute> {
}
}
+ // TODO(b/65746853): Remove documentation about accepting BuildConfiguration when uses are cleaned
+ // up.
/**
- * Marker interface for late-bound values. Unfortunately, we can't refer to BuildConfiguration
- * right now, since that is in a separate compilation unit.
- *
- * <p>Implementations of this interface must be immutable.
+ * Provider of values for late-bound attributes. See
+ * {@link Attribute#value(LateBoundDefault<?, ? extends TYPE> value)}.
*
* <p>Use sparingly - having different values for attributes during loading and analysis can
* confuse users.
+ *
+ * @param <FragmentT> The type of value that is used to compute this value. This is usually a
+ * subclass of BuildConfiguration.Fragment. It may also be Void to receive null, or
+ * BuildConfiguration itself to receive the entire configuration.
+ * @param <ValueT> The type of value returned by this class.
*/
- public interface LateBoundDefault<T> {
+ @Immutable
+ public static final class LateBoundDefault<FragmentT, ValueT> {
/**
- * Whether to look up the label in the host configuration. This is only here for host
- * compilation tools - we usually need to look up labels in the target configuration.
+ * Functional interface for computing the value of a late-bound attribute.
*
- * <p>This method only sets the configuration passed to {@link #resolve}. If you want the
- * dependency to also be analyzed in the host configuration, use
- * {@link ConfigurationTransition#HOST}.
+ * <p>Implementations of this interface must be immutable.
*/
- boolean useHostConfiguration();
+ @FunctionalInterface
+ public interface Resolver<FragmentT, ValueT> {
+ ValueT resolve(Rule rule, AttributeMap attributeMap, FragmentT input);
+ }
- /**
- * Returns the set of required configuration fragments, i.e., fragments that will be accessed by
- * the code.
- */
- Set<Class<?>> getRequiredConfigurationFragments();
+ private final boolean useHostConfiguration;
+ private final ValueT defaultValue;
+ private final Class<FragmentT> fragmentClass;
+ private final Resolver<FragmentT, ValueT> resolver;
/**
- * The default value for the attribute that is set during the loading phase.
+ * Creates a new LateBoundDefault which uses the rule, its configured attributes, and a fragment
+ * of the target configuration.
+ *
+ * <p>Note that the configuration fragment here does not take into account any transitions that
+ * are on the attribute with this LateBoundDefault as its value. The configuration will be the
+ * same as the configuration given to the target bearing the attribute.
+ *
+ * <p>Nearly all LateBoundDefaults should use this constructor. There are few situations where
+ * it isn't the appropriate option.
+ *
+ * <p>If you want a late-bound dependency which is configured in the host configuration, just
+ * use this method with {@link ConfigurationTransition#HOST}. If you also need to decide the
+ * label of the dependency with information gained from the host configuration - and it's very
+ * unlikely that you do - you can use {@link #fromHostConfiguration} as well.
+ *
+ * <p>If you want to decide an attribute's value based on the value of its other attributes,
+ * use a subclass of {@link ComputedDefault}. The only time you should need
+ * {@link #fromRuleAndAttributes} is if you need access to three or more configurable
+ * attributes, or if you need to match names with a late-bound attribute on another rule.
+ *
+ * <p>If you have a constant-valued attribute, but you need it to have the same name as an
+ * attribute on another rule which is late-bound, use {@link #fromConstant} or
+ * {@link #alwaysNull}.
+ *
+ * @param fragmentClass The fragment to receive from the target configuration. May also be
+ * BuildConfiguration.class to receive the entire configuration (deprecated) - in this case,
+ * you must only use methods of BuildConfiguration itself, and not use any fragments.
+ * @param defaultValue The default value to return at loading time, when the configuration is
+ * not available.
+ * @param resolver A function which will compute the actual value with the configuration.
*/
- Object getDefault();
+ public static <FragmentT, ValueT> LateBoundDefault<FragmentT, ValueT> fromTargetConfiguration(
+ Class<FragmentT> fragmentClass, ValueT defaultValue, Resolver<FragmentT, ValueT> resolver) {
+ Preconditions.checkArgument(
+ !fragmentClass.equals(Void.class),
+ "Use fromRuleAndAttributesOnly to specify a LateBoundDefault which does not use "
+ + "configuration.");
+ return new LateBoundDefault<>(false, fragmentClass, defaultValue, resolver);
+ }
/**
- * The actual value for the attribute for the analysis phase, which depends on the build
- * configuration. Note that configurations transitions are applied after the late-bound
- * attribute was evaluated.
+ * Creates a new LateBoundDefault which uses the rule, its configured attributes, and a fragment
+ * of the host configuration.
*
- * @param rule the rule being evaluated
- * @param attributes interface for retrieving the values of the rule's other attributes
- * @param o the configuration to evaluate with
+ * <p>This should only be necessary in very specialized cases. In almost all cases, you don't
+ * need this method, just {@link #fromTargetConfiguration} and
+ * {@link ConfigurationTransition#HOST}.
+ *
+ * <p>This method only affects the configuration fragment passed to {@link #resolve}. You must
+ * also use {@link ConfigurationTransition#HOST}, so that the dependency will be analyzed in the
+ * host configuration.
+ *
+ * @param fragmentClass The fragment to receive from the host configuration. May also be
+ * BuildConfiguration.class to receive the entire configuration (deprecated) - in this case,
+ * you must only use methods of BuildConfiguration itself, and not use any fragments.
+ * It is very rare that a LateBoundDefault should need a host configuration fragment; use
+ * {@link #fromTargetConfiguration} in most cases.
+ * @param defaultValue The default value to return at loading time, when the configuration is
+ * not available.
+ * @param resolver A function which will compute the actual value with the configuration.
+ */
+ public static <FragmentT, ValueT> LateBoundDefault<FragmentT, ValueT> fromHostConfiguration(
+ Class<FragmentT> fragmentClass, ValueT defaultValue, Resolver<FragmentT, ValueT> resolver) {
+ Preconditions.checkArgument(
+ !fragmentClass.equals(Void.class),
+ "Use fromRuleAndAttributesOnly to specify a LateBoundDefault which does not use "
+ + "configuration.");
+ return new LateBoundDefault<>(true, fragmentClass, defaultValue, resolver);
+ }
+
+ /**
+ * Creates a new LateBoundDefault which uses only the rule and its configured attributes.
+ *
+ * <p>This should only be necessary in very specialized cases. In almost all cases, you don't
+ * need this method, just use {@link ComputedDefault}.
+ *
+ * <p>This is used primarily for computing values based on three or more configurable
+ * attributes and/or matching names with late-bound attributes on other rules.
+ *
+ * @param defaultValue The default value to return when the configuration is not available at
+ * loading time.
+ * @param resolver A function which will compute the actual value with the configuration.
*/
- Object resolve(Rule rule, AttributeMap attributes, T o)
- throws EvalException, InterruptedException;
- }
-
- /**
- * Abstract super class for label-typed {@link LateBoundDefault} implementations that simplifies
- * the client code a little and makes it a bit more type-safe.
- */
- public abstract static class LateBoundLabel<T> implements LateBoundDefault<T> {
- private final Label label;
- private final ImmutableSet<Class<?>> requiredConfigurationFragments;
-
- public LateBoundLabel() {
- this((Label) null);
- }
-
- public LateBoundLabel(Class<?>... requiredConfigurationFragments) {
- this((Label) null, requiredConfigurationFragments);
+ public static <ValueT> LateBoundDefault<Void, ValueT> fromRuleAndAttributesOnly(
+ ValueT defaultValue, Resolver<Void, ValueT> resolver) {
+ return new LateBoundDefault<>(false, Void.class, defaultValue, resolver);
}
- public LateBoundLabel(Label label) {
- this.label = label;
- this.requiredConfigurationFragments = ImmutableSet.of();
+ /**
+ * Creates a new LateBoundDefault which always returns the given value.
+ *
+ * <p>This is used primarily for matching names with late-bound attributes on other rules and
+ * for testing. Use normal default values if the name does not matter.
+ */
+ public static <ValueT> LateBoundDefault<Void, ValueT> fromConstant(final ValueT defaultValue) {
+ if (defaultValue == null) {
+ return alwaysNull();
+ }
+ return new LateBoundDefault<>(
+ false, Void.class, defaultValue, (rule, attributes, unused) -> defaultValue);
}
- public LateBoundLabel(Label label, Class<?>... requiredConfigurationFragments) {
- this.label = label;
- this.requiredConfigurationFragments = ImmutableSet.copyOf(requiredConfigurationFragments);
+ /**
+ * Creates a new LateBoundDefault which always returns null.
+ *
+ * <p>This is used primarily for matching names with late-bound attributes on other rules and
+ * for testing. Use normal default values if the name does not matter.
+ */
+ @SuppressWarnings("unchecked") // bivariant implementation
+ public static <ValueT> LateBoundDefault<Void, ValueT> alwaysNull() {
+ return (LateBoundDefault<Void, ValueT>) ALWAYS_NULL;
}
- public LateBoundLabel(String label) {
- this(Label.parseAbsoluteUnchecked(label));
- }
+ private static final LateBoundDefault<Void, Void> ALWAYS_NULL =
+ new LateBoundDefault<>(false, Void.class, null, (rule, attributes, unused) -> null);
- public LateBoundLabel(String label, Class<?>... requiredConfigurationFragments) {
- this(Label.parseAbsoluteUnchecked(label), requiredConfigurationFragments);
+ private LateBoundDefault(
+ boolean useHostConfiguration,
+ Class<FragmentT> fragmentClass,
+ ValueT defaultValue,
+ Resolver<FragmentT, ValueT> resolver) {
+ this.useHostConfiguration = useHostConfiguration;
+ this.defaultValue = defaultValue;
+ this.fragmentClass = fragmentClass;
+ this.resolver = resolver;
}
- @Override
+ /**
+ * Whether to look up the label in the host configuration. This is only here for host
+ * compilation tools - we usually need to look up labels in the target configuration.
+ */
public boolean useHostConfiguration() {
- return false;
+ return useHostConfiguration;
}
- @Override
- public ImmutableSet<Class<?>> getRequiredConfigurationFragments() {
- return requiredConfigurationFragments;
- }
-
- @Override
- public final Label getDefault() {
- return label;
- }
-
- @Override
- public abstract Label resolve(Rule rule, AttributeMap attributes, T configuration);
- }
-
- /**
- * Abstract super class for label-list-typed {@link LateBoundDefault} implementations that
- * simplifies the client code a little and makes it a bit more type-safe.
- */
- public abstract static class LateBoundLabelList<T> implements LateBoundDefault<T> {
- private final ImmutableList<Label> labels;
- private final ImmutableSet<Class<?>> requiredConfigurationFragments;
-
- public LateBoundLabelList(Class<?>... requiredConfigurationFragments) {
- this(ImmutableList.<Label>of(), requiredConfigurationFragments);
- }
-
- public LateBoundLabelList(List<Label> labels, Class<?>... requiredConfigurationFragments) {
- this.labels = ImmutableList.copyOf(labels);
- this.requiredConfigurationFragments = ImmutableSet.copyOf(requiredConfigurationFragments);
- }
-
- @Override
- public boolean useHostConfiguration() {
- return false;
+ /**
+ * Returns the input type that the attribute expects. This is almost always a configuration
+ * fragment to be retrieved from the target's configuration (or the host configuration).
+ *
+ * <p>It may also be {@link Void} to receive null. This is rarely necessary, but can be used,
+ * e.g., if the attribute is named to match an attribute in another rule which is late-bound.
+ *
+ * <p>It may also be BuildConfiguration to receive the entire configuration. This is deprecated,
+ * and only necessary when the default is computed from methods of BuildConfiguration itself.
+ */
+ public Class<FragmentT> getFragmentClass() {
+ return fragmentClass;
}
- @Override
- public ImmutableSet<Class<?>> getRequiredConfigurationFragments() {
- return requiredConfigurationFragments;
+ /** The default value for the attribute that is set during the loading phase. */
+ public ValueT getDefault() {
+ return defaultValue;
}
- @Override
- public final List<Label> getDefault() {
- return labels;
+ /**
+ * The actual value for the attribute for the analysis phase, which depends on the build
+ * configuration. Note that configurations transitions are applied after the late-bound
+ * attribute was evaluated.
+ *
+ * @param rule the rule being evaluated
+ * @param attributes interface for retrieving the values of the rule's other attributes
+ * @param input the configuration fragment to evaluate with
+ */
+ public ValueT resolve(Rule rule, AttributeMap attributes, FragmentT input) {
+ return resolver.resolve(rule, attributes, input);
}
-
- @Override
- public abstract List<Label> resolve(Rule rule, AttributeMap attributes, T configuration);
}
private final String name;
@@ -1776,7 +1842,7 @@ public final class Attribute implements Comparable<Attribute> {
"late bound attributes require a default value that is late bound (and vice versa): %s",
name);
if (isLateBound(name)) {
- LateBoundDefault<?> lateBoundDefault = (LateBoundDefault<?>) defaultValue;
+ LateBoundDefault<?, ?> lateBoundDefault = (LateBoundDefault<?, ?>) defaultValue;
Preconditions.checkArgument(!lateBoundDefault.useHostConfiguration()
|| (configTransition == ConfigurationTransition.HOST),
"a late bound default value using the host configuration must use the host transition");
@@ -2045,8 +2111,8 @@ public final class Attribute implements Comparable<Attribute> {
public Object getDefaultValue(Rule rule) {
if (!getCondition().apply(rule == null ? null : NonconfigurableAttributeMapper.of(rule))) {
return null;
- } else if (defaultValue instanceof LateBoundDefault<?>) {
- return ((LateBoundDefault<?>) defaultValue).getDefault();
+ } else if (defaultValue instanceof LateBoundDefault<?, ?>) {
+ return ((LateBoundDefault<?, ?>) defaultValue).getDefault();
} else {
return defaultValue;
}
@@ -2061,9 +2127,9 @@ public final class Attribute implements Comparable<Attribute> {
return defaultValue;
}
- public LateBoundDefault<?> getLateBoundDefault() {
+ public LateBoundDefault<?, ?> getLateBoundDefault() {
Preconditions.checkState(isLateBound());
- return (LateBoundDefault<?>) defaultValue;
+ return (LateBoundDefault<?, ?>) defaultValue;
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
index 2842572fd5..b2f064848e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
@@ -39,7 +39,7 @@ import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
@@ -191,17 +191,12 @@ public final class AndroidRuleClasses {
fromTemplates("%{name}_images/emulator-meta-data.pb");
static final FileType APK = FileType.of(".apk");
- /**
- * The default label of android_sdk option
- */
- public static final class AndroidSdkLabel extends LateBoundLabel<BuildConfiguration> {
- public AndroidSdkLabel(Label androidSdk) {
- super(androidSdk, AndroidConfiguration.class);
- }
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(AndroidConfiguration.class).getSdk();
- }
+ /** The default label of android_sdk option */
+ public static LateBoundDefault<?, Label> getAndroidSdkLabel(Label androidSdk) {
+ return LateBoundDefault.fromTargetConfiguration(
+ AndroidConfiguration.class,
+ androidSdk,
+ (rule, attributes, configuration) -> configuration.getSdk());
}
public static final SplitTransition<BuildOptions> ANDROID_SPLIT_TRANSITION =
@@ -555,7 +550,7 @@ public final class AndroidRuleClasses {
.add(
attr(":android_sdk", LABEL)
.allowedRuleClasses("android_sdk", "filegroup")
- .value(new AndroidSdkLabel(env.getToolsLabel(AndroidRuleClasses.DEFAULT_SDK))))
+ .value(getAndroidSdkLabel(env.getToolsLabel(AndroidRuleClasses.DEFAULT_SDK))))
/* <!-- #BLAZE_RULE($android_base).ATTRIBUTE(plugins) -->
Java compiler plugins to run at compile-time.
Every <code>java_plugin</code> specified in
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java b/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java
index b3a5ff58e7..8f4a8ff45c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java
@@ -146,7 +146,7 @@ public final class DexArchiveAspect extends NativeAspectClass implements Configu
attr(":dex_archive_android_sdk", LABEL)
.allowedRuleClasses("android_sdk", "filegroup")
.value(
- new AndroidRuleClasses.AndroidSdkLabel(
+ AndroidRuleClasses.getAndroidSdkLabel(
Label.parseAbsoluteUnchecked(
toolsRepository + AndroidRuleClasses.DEFAULT_SDK))))
.requiresConfigurationFragments(AndroidConfiguration.class)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
index a380f52713..0cc09b83ea 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
@@ -22,12 +22,9 @@ import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.packages.AttributeMap;
-import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
@@ -151,20 +148,13 @@ public class AppleToolchain {
return sdkDir() + relativePath;
}
- /**
- * The default label of the build-wide {@code xcode_config} configuration rule.
- */
- @Immutable
- public static final class XcodeConfigLabel extends LateBoundLabel<BuildConfiguration> {
- public XcodeConfigLabel(String toolsRepository) {
- super(toolsRepository + AppleCommandLineOptions.DEFAULT_XCODE_VERSION_CONFIG_LABEL,
- AppleConfiguration.class);
- }
-
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(AppleConfiguration.class).getXcodeConfigLabel();
- }
+ /** The default label of the build-wide {@code xcode_config} configuration rule. */
+ public static LateBoundDefault<?, Label> getXcodeConfigLabel(String toolsRepository) {
+ return LateBoundDefault.fromTargetConfiguration(
+ AppleConfiguration.class,
+ Label.parseAbsoluteUnchecked(
+ toolsRepository + AppleCommandLineOptions.DEFAULT_XCODE_VERSION_CONFIG_LABEL),
+ (rule, attributes, appleConfig) -> appleConfig.getXcodeConfigLabel());
}
/**
@@ -180,11 +170,12 @@ public class AppleToolchain {
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
return builder
- .add(attr(XcodeConfigRule.XCODE_CONFIG_ATTR_NAME, LABEL)
- .allowedRuleClasses("xcode_config")
- .checkConstraints()
- .direct_compile_time_input()
- .value(new XcodeConfigLabel(toolsRepository)))
+ .add(
+ attr(XcodeConfigRule.XCODE_CONFIG_ATTR_NAME, LABEL)
+ .allowedRuleClasses("xcode_config")
+ .checkConstraints()
+ .direct_compile_time_input()
+ .value(getXcodeConfigLabel(toolsRepository)))
.build();
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
index 0bd4093864..11781594b5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
@@ -70,7 +70,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
public static final String CC_TOOLCHAIN_DEFAULT_ATTRIBUTE_NAME = ":cc_toolchain";
/** Default attribute name for the c++ toolchain type */
- public static final String CC_TOOLCHAIN_TYPE_ATTRIBUTE_NAME = ":cc_toolchain_type";
+ public static final String CC_TOOLCHAIN_TYPE_ATTRIBUTE_NAME = "$cc_toolchain_type";
/**
* This file (found under the sysroot) may be unconditionally included in every C/C++ compilation.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
index 23cc7fc326..6672ca93bd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
@@ -25,10 +25,8 @@ import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.MakeVariableInfo;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.packages.AttributeMap;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
@@ -66,13 +64,11 @@ public final class CcToolchainRule implements RuleDefinition {
return ruleClass.endsWith("cc_toolchain");
}
- private static final LateBoundLabel<BuildConfiguration> LIBC_TOP =
- new LateBoundLabel<BuildConfiguration>(CppConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(CppConfiguration.class).getSysrootLabel();
- }
- };
+ private static final LateBoundDefault<?, Label> LIBC_TOP =
+ LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ null,
+ (rule, attributes, cppConfig) -> cppConfig.getSysrootLabel());
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
@@ -117,19 +113,11 @@ public final class CcToolchainRule implements RuleDefinition {
.cfg(HOST)
.singleArtifact()
.value(
- new LateBoundLabel<BuildConfiguration>() {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- CppConfiguration cppConfiguration =
- configuration.getFragment(CppConfiguration.class);
- if (cppConfiguration.isLLVMOptimizedFdo()) {
- return zipper;
- } else {
- return null;
- }
- }
- }))
+ LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ null,
+ (rule, attributes, cppConfig) ->
+ cppConfig.isLLVMOptimizedFdo() ? zipper : null)))
.add(attr(":libc_top", LABEL).value(LIBC_TOP))
.add(
attr(":lipo_context_collector", LABEL)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
index 953044781b..a4ad59ec05 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
@@ -33,16 +33,13 @@ import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.VERSIONED_SHA
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.LanguageDependentFragment.LibraryLanguage;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.PatchTransition;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.Attribute.Transition;
-import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleTransitionFactory;
import com.google.devtools.build.lib.rules.cpp.transitions.DisableLipoTransition;
import com.google.devtools.build.lib.rules.cpp.transitions.EnableLipoTransition;
@@ -55,17 +52,16 @@ import com.google.devtools.build.lib.util.OsUtils;
public class CppRuleClasses {
/**
* Implementation for the :lipo_context_collector attribute.
+ *
+ * <p>This attribute connects a target to the LIPO context target configured with the lipo input
+ * collector configuration.
*/
- public static final LateBoundLabel<BuildConfiguration> LIPO_CONTEXT_COLLECTOR =
- new LateBoundLabel<BuildConfiguration>() {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- // This attribute connects a target to the LIPO context target configured with the
- // lipo input collector configuration.
- CppConfiguration cppConfiguration = configuration.getFragment(CppConfiguration.class);
- return cppConfiguration.isLipoOptimization() ? cppConfiguration.getLipoContextLabel() : null;
- }
- };
+ public static final LateBoundDefault<?, Label> LIPO_CONTEXT_COLLECTOR =
+ LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ null,
+ (rule, attributes, cppConfig) ->
+ cppConfig.isLipoOptimization() ? cppConfig.getLipoContextLabel() : null);
/**
* Declares the implementations for C++ transition enums.
@@ -91,34 +87,20 @@ public class CppRuleClasses {
*/
public static final String CROSSTOOL_LABEL = "//tools/cpp:toolchain";
- public static final LateBoundLabel<BuildConfiguration> DEFAULT_MALLOC =
- new LateBoundLabel<BuildConfiguration>() {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(CppConfiguration.class).customMalloc();
- }
- };
+ public static final LateBoundDefault<?, Label> DEFAULT_MALLOC =
+ LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class, null, (rule, attributes, cppConfig) -> cppConfig.customMalloc());
- public static LateBoundLabel<BuildConfiguration> ccToolchainAttribute(
+ public static LateBoundDefault<CppConfiguration, Label> ccToolchainAttribute(
RuleDefinitionEnvironment env) {
- return new LateBoundLabel<BuildConfiguration>(
- env.getToolsLabel(CROSSTOOL_LABEL), CppConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(CppConfiguration.class).getCcToolchainRuleLabel();
- }
- };
+ return LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ env.getToolsLabel(CROSSTOOL_LABEL),
+ (rules, attributes, cppConfig) -> cppConfig.getCcToolchainRuleLabel());
}
- public static LateBoundLabel<BuildConfiguration> ccToolchainTypeAttribute(
- RuleDefinitionEnvironment env) {
- return new LateBoundLabel<BuildConfiguration>(
- env.getToolsLabel(CppHelper.TOOLCHAIN_TYPE_LABEL), CppConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return CppHelper.getCcToolchainType(env.getToolsRepository());
- }
- };
+ public static Label ccToolchainTypeAttribute(RuleDefinitionEnvironment env) {
+ return env.getToolsLabel(CppHelper.TOOLCHAIN_TYPE_LABEL);
}
// Artifacts of these types are discarded from the 'hdrs' attribute in cc rules
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
index dd73adffd1..35538cc8c0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
@@ -31,16 +31,13 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.NativeAspectClass;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.cpp.CcCommon;
import com.google.devtools.build.lib.rules.cpp.CcLibraryHelper;
@@ -71,21 +68,17 @@ public class CcProtoAspect extends NativeAspectClass implements ConfiguredAspect
private static final String PROTO_TOOLCHAIN_ATTR = ":aspect_cc_proto_toolchain";
- private static final Attribute.LateBoundLabel<BuildConfiguration> PROTO_TOOLCHAIN_LABEL =
- new Attribute.LateBoundLabel<BuildConfiguration>(
- "@com_google_protobuf_cc//:cc_toolchain", ProtoConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(ProtoConfiguration.class).protoToolchainForCc();
- }
- };
+ private static final Attribute.LateBoundDefault<?, Label> PROTO_TOOLCHAIN_LABEL =
+ Attribute.LateBoundDefault.fromTargetConfiguration(
+ ProtoConfiguration.class,
+ Label.parseAbsoluteUnchecked("@com_google_protobuf_cc//:cc_toolchain"),
+ (rule, attributes, protoConfig) -> protoConfig.protoToolchainForCc());
private final CppSemantics cppSemantics;
- private final Attribute.LateBoundLabel<BuildConfiguration> ccToolchainAttrValue;
+ private final Attribute.LateBoundDefault<?, Label> ccToolchainAttrValue;
public CcProtoAspect(
- CppSemantics cppSemantics,
- Attribute.LateBoundLabel<BuildConfiguration> ccToolchainAttrValue) {
+ CppSemantics cppSemantics, Attribute.LateBoundDefault<?, Label> ccToolchainAttrValue) {
this.cppSemantics = cppSemantics;
this.ccToolchainAttrValue = ccToolchainAttrValue;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java
index 67e5a6f8b7..1bd75edd74 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java
@@ -25,13 +25,12 @@ import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.MakeVariableInfo;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.packages.Attribute.ComputedDefault;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
@@ -50,29 +49,25 @@ public class GenRuleBaseRule implements RuleDefinition {
* Late-bound dependency on the C++ toolchain <i>iff</i> the genrule has make variables that need
* that toolchain.
*/
- public static Attribute.LateBoundLabel<BuildConfiguration> ccToolchainAttribute(
- RuleDefinitionEnvironment env) {
- return new LateBoundLabel<BuildConfiguration>(
- env.getToolsLabel(CppRuleClasses.CROSSTOOL_LABEL), CppConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return attributes != null
- && GenRuleBase.requiresCrosstool(attributes.get("cmd", Type.STRING))
- ? CppRuleClasses.ccToolchainAttribute(env).resolve(rule, attributes, configuration)
- : null;
- }
- };
+ public static LateBoundDefault<?, Label> ccToolchainAttribute(RuleDefinitionEnvironment env) {
+ return LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ env.getToolsLabel(CppRuleClasses.CROSSTOOL_LABEL),
+ // null guards are needed for LateBoundAttributeTest
+ (rule, attributes, cppConfig) ->
+ attributes != null
+ && attributes.get("cmd", Type.STRING) != null
+ && GenRuleBase.requiresCrosstool(attributes.get("cmd", Type.STRING))
+ ? CppRuleClasses.ccToolchainAttribute(env).resolve(rule, attributes, cppConfig)
+ : null);
}
- /** Late-bound dependency on the C++ toolchain type. */
- public static Attribute.LateBoundLabel<BuildConfiguration> ccToolchainTypeAttribute(
- RuleDefinitionEnvironment env) {
- return new LateBoundLabel<BuildConfiguration>(
- env.getToolsLabel(CppHelper.TOOLCHAIN_TYPE_LABEL), CppConfiguration.class) {
+ /** Computed dependency on the C++ toolchain type. */
+ public static ComputedDefault ccToolchainTypeAttribute(RuleDefinitionEnvironment env) {
+ return new ComputedDefault("cmd") {
@Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return attributes != null
- && GenRuleBase.requiresCrosstool(attributes.get("cmd", Type.STRING))
+ public Object getDefault(AttributeMap rule) {
+ return GenRuleBase.requiresCrosstool(rule.get("cmd", Type.STRING))
? CppHelper.getCcToolchainType(env.getToolsRepository())
: null;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
index f83d0fe82e..ca43c7e92e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
@@ -35,11 +35,8 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabelList;
-import com.google.devtools.build.lib.packages.AttributeMap;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.rules.java.DeployArchiveBuilder.Compression;
import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType;
import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode;
@@ -112,14 +109,11 @@ public interface JavaSemantics {
/** The java_toolchain.compatible_javacopts key for proto compilations. */
public static final String PROTO_JAVACOPTS_KEY = "proto";
- LateBoundLabel<BuildConfiguration> JAVA_TOOLCHAIN =
- new LateBoundLabel<BuildConfiguration>(JAVA_TOOLCHAIN_LABEL, JavaConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes,
- BuildConfiguration configuration) {
- return configuration.getFragment(JavaConfiguration.class).getToolchainLabel();
- }
- };
+ LateBoundDefault<?, Label> JAVA_TOOLCHAIN =
+ LateBoundDefault.fromTargetConfiguration(
+ JavaConfiguration.class,
+ Label.parseAbsoluteUnchecked(JAVA_TOOLCHAIN_LABEL),
+ (rule, attributes, javaConfig) -> javaConfig.getToolchainLabel());
/**
* Name of the output group used for source jars.
@@ -135,111 +129,86 @@ public interface JavaSemantics {
OutputGroupProvider.HIDDEN_OUTPUT_GROUP_PREFIX + "gen_jars";
/** Implementation for the :jvm attribute. */
- static LateBoundLabel<BuildConfiguration> jvmAttribute(RuleDefinitionEnvironment env) {
- return new LateBoundLabel<BuildConfiguration>(
- env.getToolsLabel(JavaImplicitAttributes.JDK_LABEL), Jvm.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(Jvm.class).getJvmLabel();
- }
- };
+ static LateBoundDefault<?, Label> jvmAttribute(RuleDefinitionEnvironment env) {
+ return LateBoundDefault.fromTargetConfiguration(
+ Jvm.class,
+ env.getToolsLabel(JavaImplicitAttributes.JDK_LABEL),
+ (rule, attributes, jvm) -> jvm.getJvmLabel());
}
/** Implementation for the :host_jdk attribute. */
- static LateBoundLabel<BuildConfiguration> hostJdkAttribute(RuleDefinitionEnvironment env) {
- return new LateBoundLabel<BuildConfiguration>(
- env.getToolsLabel(JavaImplicitAttributes.JDK_LABEL), Jvm.class) {
- @Override
- public boolean useHostConfiguration() {
- return true;
- }
-
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(Jvm.class).getJvmLabel();
- }
- };
+ static LateBoundDefault<?, Label> hostJdkAttribute(RuleDefinitionEnvironment env) {
+ return LateBoundDefault.fromHostConfiguration(
+ Jvm.class,
+ env.getToolsLabel(JavaImplicitAttributes.JDK_LABEL),
+ (rule, attributes, jvm) -> jvm.getJvmLabel());
}
/**
* Implementation for the :java_launcher attribute. Note that the Java launcher is disabled by
* default, so it returns null for the configuration-independent default value.
*/
- LateBoundLabel<BuildConfiguration> JAVA_LAUNCHER =
- new LateBoundLabel<BuildConfiguration>(JavaConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- // This nullness check is purely for the sake of a test that doesn't bother to include an
- // attribute map when calling this method.
- if (attributes != null) {
- // Don't depend on the launcher if we don't create an executable anyway
- if (attributes.has("create_executable")
- && !attributes.get("create_executable", Type.BOOLEAN)) {
- return null;
+ LateBoundDefault<?, Label> JAVA_LAUNCHER =
+ LateBoundDefault.fromTargetConfiguration(
+ JavaConfiguration.class,
+ null,
+ (rule, attributes, javaConfig) -> {
+ // This nullness check is purely for the sake of a test that doesn't bother to include
+ // an
+ // attribute map when calling this method.
+ if (attributes != null) {
+ // Don't depend on the launcher if we don't create an executable anyway
+ if (attributes.has("create_executable")
+ && !attributes.get("create_executable", Type.BOOLEAN)) {
+ return null;
+ }
+
+ // don't read --java_launcher if this target overrides via a launcher attribute
+ if (attributes.isAttributeValueExplicitlySpecified("launcher")) {
+ return attributes.get("launcher", LABEL);
+ }
}
-
- // don't read --java_launcher if this target overrides via a launcher attribute
- if (attributes.isAttributeValueExplicitlySpecified("launcher")) {
- return attributes.get("launcher", LABEL);
+ return javaConfig.getJavaLauncherLabel();
+ });
+
+ // TODO(b/65746853): provide a way to do this without passing the entire configuration
+ LateBoundDefault<?, List<Label>> JAVA_PLUGINS =
+ LateBoundDefault.fromTargetConfiguration(
+ BuildConfiguration.class,
+ ImmutableList.of(),
+ (rule, attributes, configuration) -> ImmutableList.copyOf(configuration.getPlugins()));
+
+ /** Implementation for the :proguard attribute. */
+ LateBoundDefault<?, Label> PROGUARD =
+ LateBoundDefault.fromTargetConfiguration(
+ JavaConfiguration.class,
+ null,
+ (rule, attributes, javaConfig) -> javaConfig.getProguardBinary());
+
+ LateBoundDefault<?, List<Label>> EXTRA_PROGUARD_SPECS =
+ LateBoundDefault.fromTargetConfiguration(
+ JavaConfiguration.class,
+ ImmutableList.of(),
+ (rule, attributes, javaConfig) ->
+ ImmutableList.copyOf(javaConfig.getExtraProguardSpecs()));
+
+ LateBoundDefault<?, List<Label>> BYTECODE_OPTIMIZERS =
+ LateBoundDefault.fromTargetConfiguration(
+ JavaConfiguration.class,
+ ImmutableList.of(),
+ (rule, attributes, javaConfig) -> {
+ // Use a modicum of smarts to avoid implicit dependencies where we don't need them.
+ JavaOptimizationMode optMode = javaConfig.getJavaOptimizationMode();
+ boolean hasProguardSpecs =
+ attributes.has("proguard_specs")
+ && !attributes.get("proguard_specs", LABEL_LIST).isEmpty();
+ if (optMode == JavaOptimizationMode.NOOP
+ || (optMode == JavaOptimizationMode.LEGACY && !hasProguardSpecs)) {
+ return ImmutableList.<Label>of();
}
- }
- return configuration.getFragment(JavaConfiguration.class).getJavaLauncherLabel();
- }
- };
-
- LateBoundLabelList<BuildConfiguration> JAVA_PLUGINS =
- new LateBoundLabelList<BuildConfiguration>() {
- @Override
- public List<Label> resolve(Rule rule, AttributeMap attributes,
- BuildConfiguration configuration) {
- return ImmutableList.copyOf(configuration.getPlugins());
- }
- };
-
- /**
- * Implementation for the :proguard attribute.
- */
- LateBoundLabel<BuildConfiguration> PROGUARD =
- new LateBoundLabel<BuildConfiguration>(JavaConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes,
- BuildConfiguration configuration) {
- return configuration.getFragment(JavaConfiguration.class).getProguardBinary();
- }
- };
-
- LateBoundLabelList<BuildConfiguration> EXTRA_PROGUARD_SPECS =
- new LateBoundLabelList<BuildConfiguration>() {
- @Override
- public List<Label> resolve(Rule rule, AttributeMap attributes,
- BuildConfiguration configuration) {
- return ImmutableList.copyOf(
- configuration.getFragment(JavaConfiguration.class).getExtraProguardSpecs());
- }
- };
-
- LateBoundLabelList<BuildConfiguration> BYTECODE_OPTIMIZERS =
- new LateBoundLabelList<BuildConfiguration>(JavaConfiguration.class) {
- @Override
- public List<Label> resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- // Use a modicum of smarts to avoid implicit dependencies where we don't need them.
- JavaOptimizationMode optMode =
- configuration.getFragment(JavaConfiguration.class).getJavaOptimizationMode();
- boolean hasProguardSpecs = attributes.has("proguard_specs")
- && !attributes.get("proguard_specs", LABEL_LIST).isEmpty();
- if (optMode == JavaOptimizationMode.NOOP
- || (optMode == JavaOptimizationMode.LEGACY && !hasProguardSpecs)) {
- return ImmutableList.<Label>of();
- }
- return ImmutableList.copyOf(
- Optional.presentInstances(
- configuration
- .getFragment(JavaConfiguration.class)
- .getBytecodeOptimizers()
- .values()));
- }
- };
+ return ImmutableList.copyOf(
+ Optional.presentInstances(javaConfig.getBytecodeOptimizers().values()));
+ });
String IJAR_LABEL = "//tools/defaults:ijar";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
index fbf667e4d8..9b09be1b1a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
@@ -35,7 +35,6 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMapBuilder;
import com.google.devtools.build.lib.analysis.WrappingProvider;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.cmdline.Label;
@@ -45,10 +44,8 @@ import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.packages.AttributeMap;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.NativeAspectClass;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
import com.google.devtools.build.lib.rules.java.JavaCompilationArtifacts;
import com.google.devtools.build.lib.rules.java.JavaCompilationHelper;
@@ -72,28 +69,24 @@ public class JavaLiteProtoAspect extends NativeAspectClass implements Configured
public static final String PROTO_TOOLCHAIN_ATTR = ":aspect_proto_toolchain_for_javalite";
- public static Attribute.LateBoundLabel<BuildConfiguration> getProtoToolchainLabel(
- String defaultValue) {
- return new Attribute.LateBoundLabel<BuildConfiguration>(
- defaultValue, ProtoConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(ProtoConfiguration.class).protoToolchainForJavaLite();
- }
- };
+ public static LateBoundDefault<?, Label> getProtoToolchainLabel(String defaultValue) {
+ return LateBoundDefault.fromTargetConfiguration(
+ ProtoConfiguration.class,
+ Label.parseAbsoluteUnchecked(defaultValue),
+ (rule, attributes, protoConfig) -> protoConfig.protoToolchainForJavaLite());
}
private final JavaSemantics javaSemantics;
@Nullable private final String jacocoLabel;
private final String defaultProtoToolchainLabel;
- private final LateBoundLabel<BuildConfiguration> hostJdkAttribute;
+ private final LateBoundDefault<?, Label> hostJdkAttribute;
public JavaLiteProtoAspect(
JavaSemantics javaSemantics,
@Nullable String jacocoLabel,
String defaultProtoToolchainLabel,
- LateBoundLabel<BuildConfiguration> hostJdkAttribute) {
+ LateBoundDefault<?, Label> hostJdkAttribute) {
this.javaSemantics = javaSemantics;
this.jacocoLabel = jacocoLabel;
this.defaultProtoToolchainLabel = defaultProtoToolchainLabel;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
index ec843a00d8..91e4b3b734 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
@@ -34,7 +34,6 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMapBuilder;
import com.google.devtools.build.lib.analysis.WrappingProvider;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.cmdline.Label;
@@ -44,10 +43,8 @@ import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.packages.AttributeMap;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.NativeAspectClass;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
import com.google.devtools.build.lib.rules.java.JavaCompilationHelper;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
@@ -71,17 +68,13 @@ import javax.annotation.Nullable;
public class JavaProtoAspect extends NativeAspectClass implements ConfiguredAspectFactory {
private static final String SPEED_PROTO_TOOLCHAIN_ATTR = ":aspect_java_proto_toolchain";
- private final LateBoundLabel<BuildConfiguration> hostJdkAttribute;
-
- private static Attribute.LateBoundLabel<BuildConfiguration> getSpeedProtoToolchainLabel(
- String defaultValue) {
- return new Attribute.LateBoundLabel<BuildConfiguration>(
- defaultValue, ProtoConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(ProtoConfiguration.class).protoToolchainForJava();
- }
- };
+ private final LateBoundDefault<?, Label> hostJdkAttribute;
+
+ private static LateBoundDefault<?, Label> getSpeedProtoToolchainLabel(String defaultValue) {
+ return LateBoundDefault.fromTargetConfiguration(
+ ProtoConfiguration.class,
+ Label.parseAbsoluteUnchecked(defaultValue),
+ (rule, attributes, protoConfig) -> protoConfig.protoToolchainForJava());
}
private final JavaSemantics javaSemantics;
@@ -95,7 +88,7 @@ public class JavaProtoAspect extends NativeAspectClass implements ConfiguredAspe
@Nullable String jacocoLabel,
RpcSupport rpcSupport,
String defaultSpeedProtoToolchainLabel,
- LateBoundLabel<BuildConfiguration> hostJdkAttribute) {
+ LateBoundDefault<?, Label> hostJdkAttribute) {
this.javaSemantics = javaSemantics;
this.jacocoLabel = jacocoLabel;
this.rpcSupport = rpcSupport;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
index 78aaba6988..d5d5851072 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
@@ -27,9 +27,8 @@ import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute.ComputedDefault;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
@@ -140,21 +139,16 @@ public class IosTestRule implements RuleDefinition {
attr(IosTest.OBJC_GCOV_ATTR, LABEL)
.cfg(HOST)
.value(env.getToolsLabel("//tools/objc:gcov")))
+ // TODO(b/65746853): provide a way to do this without passing the entire configuration
.add(
attr(IosTest.MCOV_TOOL_ATTR, LABEL)
.cfg(HOST)
.value(
- new LateBoundLabel<BuildConfiguration>(mcov) {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- if (!configuration.isCodeCoverageEnabled()) {
- return null;
- }
-
- return mcov;
- }
- }))
+ LateBoundDefault.fromTargetConfiguration(
+ BuildConfiguration.class,
+ mcov,
+ (rule, attributes, configuration) ->
+ configuration.isCodeCoverageEnabled() ? mcov : null)))
.cfg(AppleCrosstoolTransition.APPLE_CROSSTOOL_TRANSITION)
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
index 016ec5c091..87c24ab678 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
@@ -37,18 +37,15 @@ import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorAr
import com.google.devtools.build.lib.analysis.actions.ParamFileInfo;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.packages.AttributeMap;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NativeAspectClass;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.AppleToolchain;
@@ -105,13 +102,11 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
protected static final ImmutableList<String> J2OBJC_PLUGIN_PARAMS =
ImmutableList.of("file_dir_mapping", "generate_class_mappings");
- private static final LateBoundLabel<BuildConfiguration> DEAD_CODE_REPORT =
- new LateBoundLabel<BuildConfiguration>(J2ObjcConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(J2ObjcConfiguration.class).deadCodeReport().orNull();
- }
- };
+ private static final LateBoundDefault<?, Label> DEAD_CODE_REPORT =
+ LateBoundDefault.fromTargetConfiguration(
+ J2ObjcConfiguration.class,
+ null,
+ (rule, attributes, j2objcConfig) -> j2objcConfig.deadCodeReport().orNull());
/** Adds additional attribute aspects and attributes to the given AspectDefinition.Builder. */
protected AspectDefinition.Builder addAdditionalAttributes(AspectDefinition.Builder builder) {
@@ -182,14 +177,12 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
.value(
Label.parseAbsoluteUnchecked(
toolsRepository + "//third_party/java/j2objc:jre_emul.jar")))
+ .add(attr(":dead_code_report", LABEL).cfg(HOST).value(DEAD_CODE_REPORT))
.add(
- attr(":dead_code_report", LABEL)
- .cfg(HOST)
- .value(DEAD_CODE_REPORT))
- .add(attr("$jre_lib", LABEL)
- .value(
- Label.parseAbsoluteUnchecked(
- toolsRepository + "//third_party/java/j2objc:jre_core_lib")))
+ attr("$jre_lib", LABEL)
+ .value(
+ Label.parseAbsoluteUnchecked(
+ toolsRepository + "//third_party/java/j2objc:jre_core_lib")))
.add(
attr("$protobuf_lib", LABEL)
.value(
@@ -210,7 +203,7 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
.allowedRuleClasses("xcode_config")
.checkConstraints()
.direct_compile_time_input()
- .value(new AppleToolchain.XcodeConfigLabel(toolsRepository)))
+ .value(AppleToolchain.getXcodeConfigLabel(toolsRepository)))
.add(
attr("$zipper", LABEL)
.cfg(HOST)
@@ -224,8 +217,12 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
toolsRepository + "//tools/j2objc:j2objc_proto_blacklist"))))
.add(attr(":j2objc_cc_toolchain", LABEL).value(ObjcRuleClasses.APPLE_TOOLCHAIN))
.add(
+ // Objc builds do not use a lipo context collector, but must specify the attribute as
+ // a late-bound attribute to match with the similar attribute on the cc rules.
+ // TODO(b/28084560): Allow :lipo_context_collector not to be set instead of having a
+ // null instance.
attr(":lipo_context_collector", LABEL)
- .value(ObjcRuleClasses.NULL_LIPO_CONTEXT_COLLECTOR)
+ .value(LateBoundDefault.alwaysNull())
.skipPrereqValidatorCheck())
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index 2fee1f098f..56c7ae505b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -41,11 +41,10 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
+import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
@@ -160,30 +159,13 @@ public class ObjcRuleClasses {
/**
* Late-bound attribute giving the CcToolchain for CROSSTOOL_LABEL.
*
- * TODO(cpeyser): Use AppleCcToolchain instead of CcToolchain once released.
+ * <p>TODO(cpeyser): Use AppleCcToolchain instead of CcToolchain once released.
*/
- public static final LateBoundLabel<BuildConfiguration> APPLE_TOOLCHAIN =
- new LateBoundLabel<BuildConfiguration>(CROSSTOOL_LABEL, CppConfiguration.class) {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration.getFragment(CppConfiguration.class).getCcToolchainRuleLabel();
- }
- };
-
- /**
- * A null value for the lipo context collector. Objc builds do not use a lipo context collector.
- */
- // TODO(b/28084560): Allow :lipo_context_collector not to be set instead of having a null
- // instance.
- public static final LateBoundLabel<BuildConfiguration> NULL_LIPO_CONTEXT_COLLECTOR =
- new LateBoundLabel<BuildConfiguration>() {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return null;
- }
- };
+ public static final LateBoundDefault<?, Label> APPLE_TOOLCHAIN =
+ LateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ Label.parseAbsoluteUnchecked(CROSSTOOL_LABEL),
+ (rule, attributes, cppConfig) -> cppConfig.getCcToolchainRuleLabel());
/**
* Creates a new spawn action builder with apple environment variables set that are typically
@@ -543,8 +525,12 @@ public class ObjcRuleClasses {
attr(CcToolchain.CC_TOOLCHAIN_TYPE_ATTRIBUTE_NAME, LABEL)
.value(CppRuleClasses.ccToolchainTypeAttribute(env)))
.add(
+ // Objc builds do not use a lipo context collector, but must specify the attribute as
+ // a late-bound attribute to match with the similar attribute on the cc rules.
+ // TODO(b/28084560): Allow :lipo_context_collector not to be set instead of having a
+ // null instance.
attr(":lipo_context_collector", LABEL)
- .value(NULL_LIPO_CONTEXT_COLLECTOR)
+ .value(LateBoundDefault.alwaysNull())
.skipPrereqValidatorCheck())
.build();
}
@@ -677,7 +663,7 @@ public class ObjcRuleClasses {
.direct_compile_time_input()
.allowedRuleClasses(ALLOWED_CC_DEPS_RULE_CLASSES)
.mandatoryProviders(ObjcProvider.SKYLARK_CONSTRUCTOR.id())
- .allowedFileTypes())
+ .allowedFileTypes())
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(runtime_deps) -->
The list of framework targets that are late loaded at runtime. They are included in the
app bundle but not linked against at build time.
@@ -721,9 +707,7 @@ public class ObjcRuleClasses {
If specified, Bazel will not generate a module map for this target, but will pass the
provided module map to the compiler.
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(
- attr("module_map", LABEL)
- .allowedFileTypes(FileType.of(".modulemap")))
+ .add(attr("module_map", LABEL).allowedFileTypes(FileType.of(".modulemap")))
/* Provides the label for header_scanner tool that is used to scan inclusions for ObjC
sources and provide a list of required headers via a .header_list file.
@@ -735,33 +719,21 @@ public class ObjcRuleClasses {
attr(HEADER_SCANNER_ATTRIBUTE, LABEL)
.cfg(HOST)
.value(
- new LateBoundLabel<BuildConfiguration>(
+ LateBoundDefault.fromTargetConfiguration(
+ ObjcConfiguration.class,
env.getToolsLabel("//tools/objc:header_scanner"),
- ObjcConfiguration.class) {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration
- .getFragment(ObjcConfiguration.class)
- .getObjcHeaderScannerTool();
- }
- }))
+ (rule, attributes, objcConfig) -> objcConfig.getObjcHeaderScannerTool())))
.add(
attr(APPLE_SDK_ATTRIBUTE, LABEL)
.value(
- new LateBoundLabel<BuildConfiguration>(ObjcConfiguration.class) {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- ObjcConfiguration objcConfiguration =
- configuration.getFragment(ObjcConfiguration.class);
+ LateBoundDefault.fromTargetConfiguration(
+ ObjcConfiguration.class,
+ null,
// Apple SDKs are currently only used by ObjC header thinning feature
- if (objcConfiguration.useExperimentalHeaderThinning()) {
- return objcConfiguration.getAppleSdk();
- }
- return null;
- }
- }))
+ (rule, attributes, objcConfig) ->
+ objcConfig.useExperimentalHeaderThinning()
+ ? objcConfig.getAppleSdk()
+ : null)))
.build();
}
@Override
@@ -1191,15 +1163,10 @@ public class ObjcRuleClasses {
.singleArtifact()
.cfg(HOST)
.value(
- new LateBoundLabel<BuildConfiguration>(ObjcConfiguration.class) {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- return configuration
- .getFragment(ObjcConfiguration.class)
- .getExtraEntitlements();
- }
- })
+ LateBoundDefault.fromTargetConfiguration(
+ ObjcConfiguration.class,
+ null,
+ (rule, attributes, objcConfig) -> objcConfig.getExtraEntitlements()))
.allowedFileTypes(ENTITLEMENTS_TYPE))
.add(
attr(DEBUG_ENTITLEMENTS_ATTR, LABEL)
@@ -1222,22 +1189,20 @@ public class ObjcRuleClasses {
.singleArtifact()
.allowedFileTypes(FileType.of(".mobileprovision"))
.value(
- new LateBoundLabel<BuildConfiguration>(ObjcConfiguration.class) {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- AppleConfiguration appleConfiguration =
- configuration.getFragment(AppleConfiguration.class);
- if (appleConfiguration.getMultiArchPlatform(PlatformType.IOS)
- != ApplePlatform.IOS_DEVICE) {
- return null;
- }
- if (rule.isAttributeValueExplicitlySpecified(PROVISIONING_PROFILE_ATTR)) {
- return null;
- }
- return appleConfiguration.getDefaultProvisioningProfileLabel();
- }
- }))
+ LateBoundDefault.fromTargetConfiguration(
+ AppleConfiguration.class,
+ null,
+ (rule, attributes, appleConfig) -> {
+ if (appleConfig.getMultiArchPlatform(PlatformType.IOS)
+ != ApplePlatform.IOS_DEVICE) {
+ return null;
+ }
+ if (attributes.isAttributeValueExplicitlySpecified(
+ PROVISIONING_PROFILE_ATTR)) {
+ return null;
+ }
+ return appleConfig.getDefaultProvisioningProfileLabel();
+ })))
/* <!-- #BLAZE_RULE($objc_release_bundling_rule).ATTRIBUTE(app_icon) -->
The name of the application icon.
@@ -1507,23 +1472,20 @@ public class ObjcRuleClasses {
.singleArtifact()
.allowedFileTypes(FileType.of(".mobileprovision"))
.value(
- new LateBoundLabel<BuildConfiguration>(ObjcConfiguration.class) {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- AppleConfiguration appleConfiguration =
- configuration.getFragment(AppleConfiguration.class);
- if (appleConfiguration.getMultiArchPlatform(PlatformType.IOS)
- != ApplePlatform.IOS_DEVICE) {
- return null;
- }
- if (rule.isAttributeValueExplicitlySpecified(
- WATCH_EXT_PROVISIONING_PROFILE_ATTR)) {
- return null;
- }
- return appleConfiguration.getDefaultProvisioningProfileLabel();
- }
- }))
+ LateBoundDefault.fromTargetConfiguration(
+ AppleConfiguration.class,
+ null,
+ (rule, attributes, appleConfig) -> {
+ if (appleConfig.getMultiArchPlatform(PlatformType.IOS)
+ != ApplePlatform.IOS_DEVICE) {
+ return null;
+ }
+ if (attributes.isAttributeValueExplicitlySpecified(
+ WATCH_EXT_PROVISIONING_PROFILE_ATTR)) {
+ return null;
+ }
+ return appleConfig.getDefaultProvisioningProfileLabel();
+ })))
/* <!-- #BLAZE_RULE($watch_extension_bundle_rule).ATTRIBUTE(ext_resources) -->
Files to include in the final watch extension bundle.
@@ -1696,23 +1658,20 @@ public class ObjcRuleClasses {
.singleArtifact()
.allowedFileTypes(FileType.of(".mobileprovision"))
.value(
- new LateBoundLabel<BuildConfiguration>(ObjcConfiguration.class) {
- @Override
- public Label resolve(
- Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- AppleConfiguration appleConfiguration =
- configuration.getFragment(AppleConfiguration.class);
- if (appleConfiguration.getMultiArchPlatform(PlatformType.IOS)
- != ApplePlatform.IOS_DEVICE) {
- return null;
- }
- if (rule.isAttributeValueExplicitlySpecified(
- WATCH_APP_PROVISIONING_PROFILE_ATTR)) {
- return null;
- }
- return appleConfiguration.getDefaultProvisioningProfileLabel();
- }
- }))
+ LateBoundDefault.fromTargetConfiguration(
+ AppleConfiguration.class,
+ null,
+ (rule, attributes, appleConfig) -> {
+ if (appleConfig.getMultiArchPlatform(PlatformType.IOS)
+ != ApplePlatform.IOS_DEVICE) {
+ return null;
+ }
+ if (attributes.isAttributeValueExplicitlySpecified(
+ WATCH_APP_PROVISIONING_PROFILE_ATTR)) {
+ return null;
+ }
+ return appleConfig.getDefaultProvisioningProfileLabel();
+ })))
/* <!-- #BLAZE_RULE($objc_resources_rule).ATTRIBUTE(app_storyboards) -->
Files which are .storyboard resources for the watch application, possibly
localizable.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java
index 168f82f415..e7891c4eb2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java
@@ -22,11 +22,8 @@ import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.AttributeMap;
-import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.util.FileType;
@@ -36,15 +33,16 @@ import com.google.devtools.build.lib.util.FileType;
*/
public final class BazelProtoLibraryRule implements RuleDefinition {
- private static final Attribute.LateBoundLabel<BuildConfiguration> PROTO_COMPILER =
- new Attribute.LateBoundLabel<BuildConfiguration>(
- "@com_google_protobuf//:protoc", ProtoConfiguration.class) {
- @Override
- public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
- Label label = configuration.getFragment(ProtoConfiguration.class).protoCompiler();
- return label != null ? label : getDefault();
- }
- };
+ private static final Label DEFAULT_PROTO_COMPILER =
+ Label.parseAbsoluteUnchecked("@com_google_protobuf//:protoc");
+ private static final Attribute.LateBoundDefault<?, Label> PROTO_COMPILER =
+ Attribute.LateBoundDefault.fromTargetConfiguration(
+ ProtoConfiguration.class,
+ DEFAULT_PROTO_COMPILER,
+ (rule, attributes, protoConfig) ->
+ protoConfig.protoCompiler() != null
+ ? protoConfig.protoCompiler()
+ : DEFAULT_PROTO_COMPILER);
@Override
public RuleClass build(Builder builder, final RuleDefinitionEnvironment env) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java
index 3f8a001961..093ec2c534 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTargetFunction.java
@@ -197,9 +197,14 @@ public class TransitiveTargetFunction
// Declared by late-bound attributes:
for (Attribute attr : rule.getAttributes()) {
- if (attr.isLateBound()) {
- addFragmentsIfNew(builder,
- attr.getLateBoundDefault().getRequiredConfigurationFragments());
+ if (attr.isLateBound()
+ && attr.getLateBoundDefault().getFragmentClass() != null
+ && BuildConfiguration.Fragment.class.isAssignableFrom(
+ attr.getLateBoundDefault().getFragmentClass())) {
+ addFragmentIfNew(
+ builder,
+ (Class<? extends BuildConfiguration.Fragment>)
+ attr.getLateBoundDefault().getFragmentClass());
}
}