Differentiate dexing and desugaring artifacts based on the minsdk
PiperOrigin-RevId: 454746208
Change-Id: I3118ec2bc345ac2a2b1b12bc7e35ab9eed9448c1
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 2c837a8..1578a06 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
@@ -272,15 +272,19 @@
if (runtimeJars != null) {
boolean basenameClash = checkBasenameClash(runtimeJars);
Set<Set<String>> aspectDexopts = aspectDexopts(ruleContext);
+ String minSdkFilenamePart = minSdkVersion > 0 ? "--min_sdk_version=" + minSdkVersion : "";
for (Artifact jar : runtimeJars) {
for (Set<String> incrementalDexopts : aspectDexopts) {
// Since we're potentially dexing the same jar multiple times with different flags, we
// need to write unique artifacts for each flag combination. Here, it is convenient to
// distinguish them by putting the flags that were used for creating the artifacts into
- // their filenames.
+ // their filenames. Since min_sdk_version is a parameter to the aspect from the
+ // android_binary target that the aspect originates from, it's handled separately so that
+ // the correct min sdk value is used.
String uniqueFilename =
(basenameClash ? jar.getRootRelativePathString() : jar.getFilename())
+ Joiner.on("").join(incrementalDexopts)
+ + minSdkFilenamePart
+ ".dex.zip";
Artifact dexArchive =
createDexArchiveAction(
@@ -486,6 +490,8 @@
NestedSet<Artifact> bootclasspath,
NestedSet<Artifact> compileTimeClasspath,
int minSdkVersion) {
+
+ String minSdkFilenamePart = minSdkVersion > 0 ? "_minsdk=" + minSdkVersion : "";
return createDesugarAction(
ruleContext,
ASPECT_DESUGAR_PREREQ,
@@ -496,6 +502,7 @@
AndroidBinary.getDxArtifact(
ruleContext,
(disambiguateBasenames ? jar.getRootRelativePathString() : jar.getFilename())
+ + minSdkFilenamePart
+ "_desugared.jar"));
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
index f0f6b3c..d6e3ba1 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.android;
import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -37,6 +38,7 @@
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.FailAction;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
+import com.google.devtools.build.lib.analysis.AnalysisResult;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
@@ -74,6 +76,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Set;
+import java.util.function.Function;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -784,6 +787,71 @@
assertThat(args).contains("28");
}
+ @Test
+ public void testSimpleAndroidBinary_multipleMinSdkVersionOnSameLibrary() throws Exception {
+ scratch.overwriteFile(
+ "java/android/BUILD",
+ "android_binary(name = 'app1',",
+ " srcs = ['A.java'],",
+ " deps = ['lib'],",
+ " manifest = 'AndroidManifest.xml',",
+ " resource_files = glob(['res/**']),",
+ " )",
+ "android_binary(name = 'app2',",
+ " srcs = ['B.java'],",
+ " deps = ['lib'],",
+ " manifest = 'AndroidManifest.xml',",
+ " resource_files = glob(['res/**']),",
+ " min_sdk_version = 28,",
+ " )",
+ "android_library(name = 'lib',",
+ " srcs = ['C.java'])");
+ AnalysisResult result =
+ update(
+ ImmutableList.of("//java/android:app1", "//java/android:app2"),
+ /* keepGoing= */ true,
+ /* loadingPhaseThreads= */ 1,
+ /* doAnalysis= */ true,
+ eventBus);
+
+ ImmutableMap<String, ConfiguredTarget> targets =
+ result.getTargetsToBuild().stream()
+ .collect(toImmutableMap(ct -> ct.getLabel().toString(), Function.identity()));
+
+ ConfiguredTarget app1 = targets.get("//java/android:app1");
+ ConfiguredTarget app2 = targets.get("//java/android:app2");
+
+ // The "lib" target is built twice: once with the default minsdk from app1, and again with
+ // min_sdk_version = 28 from app2.
+
+ List<String> libDesugarNoMinSdkArgs =
+ getGeneratingSpawnActionArgs(
+ ActionsTestUtil.getFirstArtifactEndingWith(
+ actionsTestUtil().artifactClosureOf(getFilesToBuild(app1)),
+ "/liblib.jar_desugared.jar"));
+ assertThat(libDesugarNoMinSdkArgs).doesNotContain("--min_sdk_version");
+
+ List<String> libDexNoMinSdkArgs =
+ getGeneratingSpawnActionArgs(
+ ActionsTestUtil.getFirstArtifactEndingWith(
+ actionsTestUtil().artifactClosureOf(getFilesToBuild(app1)), "/liblib.jar.dex.zip"));
+ assertThat(libDexNoMinSdkArgs).doesNotContain("--min_sdk_version");
+
+ List<String> libDesugarWithMinSdkArgs =
+ getGeneratingSpawnActionArgs(
+ ActionsTestUtil.getFirstArtifactEndingWith(
+ actionsTestUtil().artifactClosureOf(getFilesToBuild(app2)),
+ "/liblib.jar_minsdk=28_desugared.jar"));
+ assertThat(libDesugarWithMinSdkArgs).containsAtLeast("--min_sdk_version", "28").inOrder();
+
+ List<String> libDexWithMinSdkArgs =
+ getGeneratingSpawnActionArgs(
+ ActionsTestUtil.getFirstArtifactEndingWith(
+ actionsTestUtil().artifactClosureOf(getFilesToBuild(app2)),
+ "liblib.jar--min_sdk_version=28.dex.zip"));
+ assertThat(libDexWithMinSdkArgs).containsAtLeast("--min_sdk_version", "28").inOrder();
+ }
+
// regression test for #3169099
@Test
public void testBinarySrcs() throws Exception {