DexArchiveAspect find the R.jar produced by the Starlark android_library rule.
RELNOTES: None.
PiperOrigin-RevId: 234639276
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 5bb7aff..1b0bf7d 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
@@ -263,12 +263,25 @@
// These are all transitive hjars of dependencies and hjar of the jar itself
NestedSet<Artifact> compileTimeClasspath =
getJavaCompilationArgsProvider(base, ruleContext).getTransitiveCompileTimeJars();
+ ImmutableSet.Builder<Artifact> jars = ImmutableSet.builder();
+ jars.addAll(javaInfo.getDirectRuntimeJars());
+
+ // If the target is an android_library, it may be a Starlark android_library in which case
+ // get the R.jar from the AndroidIdeInfoProvider.
+ if (isAndroidLibrary(ruleContext)) {
+ Artifact rJar = getAndroidLibraryRJar(base);
+ if (rJar != null) {
+ // TODO(b/124540821): Disable R.jar desugaring (with a flag).
+ jars.add(rJar);
+ }
+ }
+
// For android_* targets we need to honor their bootclasspath (nicer in general to do so)
ImmutableList<Artifact> bootclasspath = getBootclasspath(base, ruleContext);
-
- boolean basenameClash = checkBasenameClash(javaInfo.getDirectRuntimeJars());
- for (Artifact jar : javaInfo.getDirectRuntimeJars()) {
+ ImmutableSet<Artifact> jarsToProcess = jars.build();
+ boolean basenameClash = checkBasenameClash(jarsToProcess);
+ for (Artifact jar : jarsToProcess) {
Artifact desugared =
createDesugarAction(
ruleContext, basenameClash, jar, bootclasspath, compileTimeClasspath);
@@ -300,10 +313,22 @@
}
}
} else {
+ ImmutableSet.Builder<Artifact> jars = ImmutableSet.builder();
JavaInfo javaInfo = JavaInfo.getJavaInfo(base);
if (javaInfo != null) {
- return javaInfo.getDirectRuntimeJars();
+ jars.addAll(javaInfo.getDirectRuntimeJars());
}
+
+ // The Starlark android_library does not put the R.jar file in the direct runtime deps of the
+ // JavaInfo, it can only be retrieved from the AndroidIdeInfoProvider.
+ if (isAndroidLibrary(ruleContext)) {
+ Artifact rJar = getAndroidLibraryRJar(base);
+ if (rJar != null) {
+ jars.add(rJar);
+ }
+ }
+
+ return jars.build();
}
return null;
}
@@ -318,10 +343,23 @@
return isProtoLibrary(ruleContext) ? base.getProvider(JavaCompilationArgsProvider.class) : null;
}
+ private static boolean isAndroidLibrary(RuleContext ruleContext) {
+ return "android_library".equals(ruleContext.getRule().getRuleClass());
+ }
+
private static boolean isProtoLibrary(RuleContext ruleContext) {
return "proto_library".equals(ruleContext.getRule().getRuleClass());
}
+ private static Artifact getAndroidLibraryRJar(ConfiguredTarget base) {
+ AndroidIdeInfoProvider provider =
+ (AndroidIdeInfoProvider) base.get(AndroidIdeInfoProvider.PROVIDER.getKey());
+ if (provider != null && provider.getResourceJar() != null) {
+ return provider.getResourceJar().getClassJar();
+ }
+ return null;
+ }
+
private static boolean checkBasenameClash(Iterable<Artifact> artifacts) {
HashSet<String> seen = new HashSet<>();
for (Artifact artifact : artifacts) {