Source:
<code>public String lookupVariable(String variableName) throws ExpansionException { if (variableName.equals("SRCS")) { return Artifact.joinExecPaths(" ", resolvedSrcs); } if (variableName.equals("<")) { return expandSingletonArtifact(resolvedSrcs, "$<", "input file"); } if (variableName.equals("OUTS")) { return Artifact.joinExecPaths(" ", filesToBuild); } if (variableName.equals("@")) { return expandSingletonArtifact(filesToBuild, "$@", "output file"); } if (variableName.equals("OUT_ROOT_DIR")) { Path dirPath; <START> PathFragment dirFragment; <END> if (ruleContext.getRule().hasBinaryOutput()) { dirPath = ruleContext.getConfiguration().getBinDir().getRoot().asPath(); dirFragment = ruleContext.getConfiguration().getBinFragment(); } else { dirPath = ruleContext.getConfiguration().getGenfilesDir().getRoot().asPath(); dirFragment = ruleContext.getConfiguration().getGenfilesFragment(); } PathFragment relPath = ruleContext.getRule().getLabel().getPackageIdentifier().getSourceRoot(); String outDirStr = "testing-genrules"; Path outputRootDir = dirPath.getRelative(relPath).getRelative(outDirStr); try { outputRootDir.createDirectory(); } catch (IOException e) { throw new UncheckedIOException(e); } return dirFragment.getRelative(relPath).getRelative(outDirStr).getPathString(); } if (variableName.equals("@D")) { if (Iterables.size(filesToBuild) == 1) { Artifact outputFile = Iterables.getOnlyElement(filesToBuild); PathFragment relativeOutputFile = outputFile.getExecPath(); if (relativeOutputFile.segmentCount() <= 1) { throw new IllegalStateException( "$(@D) for genrule " + ruleContext.getLabel() + " has less than one segment"); } return relativeOutputFile.getParentDirectory().getPathString(); } else { PathFragment dir; if (ruleContext.getRule().hasBinaryOutput()) { dir = ruleContext.getConfiguration().getBinFragment(); } else { dir = ruleContext.getConfiguration().getGenfilesFragment(); } PathFragment relPath = ruleContext.getRule().getLabel().getPackageIdentifier().getSourceRoot(); return dir.getRelative(relPath).getPathString(); } } return super.lookupVariable(variableName); }</code><technical_language>RuleContext#getBinOrGenfilesDirectory() instead. exact logic</technical_language>

Target:
public String lookupVariable(String variableName) throws ExpansionException { if (variableName.equals("SRCS")) { return Artifact.joinExecPaths(" ", resolvedSrcs); } if (variableName.equals("<")) { return expandSingletonArtifact(resolvedSrcs, "$<", "input file"); } if (variableName.equals("OUTS")) { return Artifact.joinExecPaths(" ", filesToBuild); } if (variableName.equals("@")) { return expandSingletonArtifact(filesToBuild, "$@", "output file"); } if (variableName.equals("RULEDIR")) { PathFragment dir = ruleContext.getBinOrGenfilesDirectory().getExecPath(); PathFragment relPath = ruleContext.getRule().getLabel().getPackageIdentifier().getSourceRoot(); return dir.getRelative(relPath).getPathString(); } if (variableName.equals("@D")) { if (Iterables.size(filesToBuild) == 1) { Artifact outputFile = Iterables.getOnlyElement(filesToBuild); PathFragment relativeOutputFile = outputFile.getExecPath(); if (relativeOutputFile.segmentCount() <= 1) { throw new IllegalStateException( "$(@D) for genrule " + ruleContext.getLabel() + " has less than one segment"); } return relativeOutputFile.getParentDirectory().getPathString(); } else { PathFragment dir; if (ruleContext.getRule().hasBinaryOutput()) { dir = ruleContext.getConfiguration().getBinFragment(); } else { dir = ruleContext.getConfiguration().getGenfilesFragment(); } PathFragment relPath = ruleContext.getRule().getLabel().getPackageIdentifier().getSourceRoot(); return dir.getRelative(relPath).getPathString(); } } return super.lookupVariable(variableName); }