diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java index 7228f4b7e8ede6..2b2ab5ce667f7c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java +++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java @@ -309,6 +309,15 @@ public String lookupVariable(String variableName) throws ExpansionException { return expandSingletonArtifact(filesToBuild, "$@", "output file"); } + if (variableName.equals("RULEDIR")) { + // The output root directory. This variable expands to the package's root directory + // in the genfiles tree. + PathFragment dir = ruleContext.getBinOrGenfilesDirectory().getExecPath(); + PathFragment relPath = + ruleContext.getRule().getLabel().getPackageIdentifier().getSourceRoot(); + return dir.getRelative(relPath).getPathString(); + } + if (variableName.equals("@D")) { // The output directory. If there is only one filename in outs, // this expands to the directory containing that file. If there are 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 c0287c3da63b0c..3534938e146b7c 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 @@ -131,9 +131,10 @@ public RuleClass build( list, not in srcs, to ensure they are built in the correct configuration.

*/ - .add(attr("tools", LABEL_LIST) - .cfg(HostTransition.INSTANCE) - .allowedFileTypes(FileTypeSet.ANY_FILE)) + .add( + attr("tools", LABEL_LIST) + .cfg(HostTransition.INSTANCE) + .allowedFileTypes(FileTypeSet.ANY_FILE)) /* A list of files generated by this rule.

@@ -161,8 +162,8 @@ public RuleClass build(

Note that outs are not included in this substitution. Output files are always generated into a predictable location (available via $(@D), - $@, $(OUTS) or $(location output_name); - see below). + $@, $(OUTS) or $(RULEDIR) or + $(location output_name); see below).

  • diff --git a/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java b/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java index 0fc6a89822890b..4c7e2191ccd554 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java @@ -241,8 +241,9 @@ public PathFragment getParentDirectory() { /** * Returns the {@link PathFragment} relative to the base {@link PathFragment}. * - *

    For example, FilePath.create("foo/bar/wiz").relativeTo(FilePath.create("foo")) - * returns "bar/wiz". + *

    For example, + * {@link PathFragment}.create("foo/bar/wiz").relativeTo({@link PathFragment}.create("foo")) + * returns "bar/wiz". * *

    If the {@link PathFragment} is not a child of the passed {@link PathFragment} an {@link * IllegalArgumentException} is thrown. In particular, this will happen whenever the two {@link diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleConfiguredTargetTest.java index ece88bdf6fdbe8..a8e9bbbf0185f1 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleConfiguredTargetTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleConfiguredTargetTest.java @@ -283,6 +283,26 @@ public void testOutputDirExpansion() throws Exception { assertThat(bazExpected.equals(barExpected)).isFalse(); } + /** Ensure that variable $(RULE_DIR) gets expanded correctly in the genrule cmd. */ + @Test + public void testRuleDirExpansion() throws Exception { + scratch.file( + "foo/BUILD", + "genrule(name = 'bar',", + " srcs = ['bar_in.txt'],", + " cmd = 'touch $(RULEDIR)',", + " outs = ['bar/bar_out.txt'])", + "genrule(name = 'baz',", + " srcs = ['bar/bar_out.txt'],", + " cmd = 'touch $(RULEDIR)',", + " outs = ['baz/baz_out.txt', 'logs/baz.log'])"); + + // Make sure the expansion for $(RULE_DIR) results in the directory of the BUILD file ("foo") + String expectedRegex = "touch b.{4}-out.*foo"; + assertThat(getCommand("//foo:bar")).containsMatch(expectedRegex); + assertThat(getCommand("//foo:baz")).containsMatch(expectedRegex); + } + /** Ensure that variable $(CC) gets expanded correctly in the genrule cmd. */ @Test public void testMakeVarExpansion() throws Exception {