RELNOTES[NEW]: The "args" attribute of *_binary and *_test rules now support expanding $(location //some/deps)
*_binary and *_test rules were supporting make variables substitution but not location expansion like genrule() does. Now the $(location //some/label) where //some/label is the label of a dependency of the rule will be replaced at runtime by the actual location of that dependency. In the same manner $(locations //some/label) will be replaced by the space separated list of files of the //some/label dependency. A longer usage explanation is provided in the build encyclopedia.
--
MOS_MIGRATED_REVID=87927345
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index eef371b..0de3117 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -593,14 +593,27 @@
}
/**
- * Gets an attribute of type STRING_LIST expanding Make variables and
- * tokenizes the result.
+ * Gets an attribute of type STRING_LIST expanding Make variables and tokenizes
+ * the result.
*
* @param attributeName the name of the attribute to process
- * @return a list of strings containing the expanded and tokenized values for the
- * attribute
+ * @return a list of strings containing the expanded and tokenized values for the attribute
*/
public List<String> getTokenizedStringListAttr(String attributeName) {
+ return getTokenizedStringListAttr(attributeName, null);
+ }
+
+ /**
+ * Gets an attribute of type STRING_LIST expanding Make variables, $(location) tags into the
+ * dependency location (see {@link LocationExpander} for details) and tokenizes the result.
+ *
+ * @param attributeName the name of the attribute to process
+ * @param ruleContext the rule context to look for $(location) tag replacement, or null if
+ * location should not be expanded
+ * @return a list of strings containing the expanded and tokenized values for the attribute
+ */
+ public List<String> getTokenizedStringListAttr(String attributeName,
+ @Nullable RuleContext ruleContext) {
if (!getRule().isAttrDefined(attributeName, Type.STRING_LIST)) {
// TODO(bazel-team): This should be an error.
return ImmutableList.of();
@@ -610,8 +623,12 @@
return ImmutableList.of();
}
List<String> tokens = new ArrayList<>();
+ LocationExpander locationExpander =
+ ruleContext != null ? new LocationExpander(ruleContext, LocationExpander.Options.ALLOW_DATA)
+ : null;
+
for (String token : original) {
- tokenizeAndExpandMakeVars(tokens, attributeName, token);
+ tokenizeAndExpandMakeVars(tokens, attributeName, token, locationExpander);
}
return ImmutableList.copyOf(tokens);
}
@@ -621,10 +638,23 @@
*
* <p>This methods should be called only during initialization.
*/
+ public void tokenizeAndExpandMakeVars(List<String> tokens, String attributeName, String value) {
+ tokenizeAndExpandMakeVars(tokens, attributeName, value, null);
+ }
+
+ /**
+ * Expands make variables and $(location) tag in value and tokenizes the result into tokens.
+ *
+ * <p>This methods should be called only during initialization.
+ */
public void tokenizeAndExpandMakeVars(List<String> tokens, String attributeName,
- String value) {
+ String value, @Nullable LocationExpander locationExpander) {
try {
- ShellUtils.tokenize(tokens, expandMakeVariables(attributeName, value));
+ if (locationExpander != null) {
+ value = locationExpander.expand(attributeName, value);
+ }
+ value = expandMakeVariables(attributeName, value);
+ ShellUtils.tokenize(tokens, value);
} catch (ShellUtils.TokenizationException e) {
attributeError(attributeName, e.getMessage());
}