Implement TODO from: https://github.com/bazelbuild/bazel/blo[]fbbd6a32b95ba746f09dae1eaeaccf675cd5b3/src/main/java/com/google/devtools/build/lib/packages/Attribute.java#L1045
This allows the default value computation for latebound attributes to consider
the values of configurable attributes. This is most directly useful for user-definable Skylark defaults, which have full access to the values of all non-latebound attributes.
Without this change, this kind of scenario crashes Bazel. For example:
------------------
select_rules.bzl:
------------------
def _impl(ctx):
ctx.file_action(
output=ctx.outputs.out_file,
content=ctx.attr.string_value,
)
return struct()
# Bug does not manifest without using this as a default.
def _derived_value(attrs, _):
return Label("//some:dep")
selector_rule = rule(
implementation=_impl,
attrs={
"string_value": attr.string(default=""),
"out_file": attr.output(),
"_derived": attr.label(default=_derived_value),
},
output_to_genfiles=True,
)
def selector_macro(name, out_file="", string_value=""):
# This will fail with selectors.
selector_rule(
name="%s_skylark" % name,
string_value=string_value,
out_file=out_file + ".skylark",
)
# This does not.
native.genrule(
name="%s_genrule" % name,
cmd="echo '" + string_value + "' > $@",
outs=[out_file + ".genrule"],
)
native.filegroup(
name=name,
srcs=[":%s_genrule" % name, "%s_skylark" % name],
)
------------------
BUILD.bzl:
------------------
config_setting(
name = "selector",
values = {"compilation_mode": "opt"},
)
selector_macro(
name = "this_rule",
string_value = """soup? """ + select({
":selector": "no, thank you.",
"//conditions:default": "yes, please!!",
}),
out_file = "this_rule.txt",
)
--
MOS_MIGRATED_REVID=114326474
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 daf6106..cd808c5 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
@@ -922,8 +922,13 @@
* 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 o the configuration to evaluate with
*/
- Object getDefault(Rule rule, T o) throws EvalException, InterruptedException;
+ Object getDefault(Rule rule, AttributeMap attributes, T o)
+ throws EvalException, InterruptedException;
}
/**
@@ -976,7 +981,7 @@
}
@Override
- public abstract Label getDefault(Rule rule, T configuration);
+ public abstract Label getDefault(Rule rule, AttributeMap attributes, T configuration);
}
/**
@@ -1010,7 +1015,7 @@
}
@Override
- public abstract List<Label> getDefault(Rule rule, T configuration);
+ public abstract List<Label> getDefault(Rule rule, AttributeMap attributes, T configuration);
}
/**
@@ -1040,11 +1045,9 @@
}
@Override
- public Object getDefault(Rule rule, Object o) throws EvalException, InterruptedException {
+ public Object getDefault(Rule rule, AttributeMap attributes, Object o)
+ throws EvalException, InterruptedException {
Map<String, Object> attrValues = new HashMap<>();
- // TODO(bazel-team): support configurable attributes here. RawAttributeMapper will throw
- // an exception on any instance of configurable attributes.
- AttributeMap attributes = RawAttributeMapper.of(rule);
for (Attribute attr : rule.getAttributes()) {
if (!attr.isLateBound()) {
Object value = attributes.get(attr.getName(), attr.getType());