Skip to content

Commit ab35c6f

Browse files
jylinv0zhaoqxu97ahumeskyiancha1992
authored
[6.3.0] Add a new provider for passing dex related artifacts in android_binary (#18899)
* Creates an AndroidDexInfo provider to pass dex related artifacts from Starlark to Native Bazel. PiperOrigin-RevId: 515061110 Change-Id: Ieefe430582c01264fb510de3ac1017d3332f51aa * Enable android_binary to use AndroidDexInfo from its application_resources attribute. android_binary will use the dexes, jar resources, and deploy jar from AndroidDexInfo if it is present. RELNOTES: None. PiperOrigin-RevId: 531000013 Change-Id: I67c3457d131041aa4bab5db0892cdc0f0584f2dc --------- Co-authored-by: Zhaoqing Xu <[email protected]> Co-authored-by: Googler <[email protected]> Co-authored-by: Ian (Hee) Cha <[email protected]>
1 parent 3c4b936 commit ab35c6f

File tree

6 files changed

+242
-13
lines changed

6 files changed

+242
-13
lines changed

src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import com.google.devtools.build.lib.rules.android.AndroidDeviceBrokerInfo;
7070
import com.google.devtools.build.lib.rules.android.AndroidDeviceRule;
7171
import com.google.devtools.build.lib.rules.android.AndroidDeviceScriptFixtureRule;
72+
import com.google.devtools.build.lib.rules.android.AndroidDexInfo;
7273
import com.google.devtools.build.lib.rules.android.AndroidFeatureFlagSetProvider;
7374
import com.google.devtools.build.lib.rules.android.AndroidHostServiceFixtureRule;
7475
import com.google.devtools.build.lib.rules.android.AndroidIdeInfoProvider;
@@ -423,7 +424,8 @@ public void init(ConfiguredRuleClassProvider.Builder builder) {
423424
ProguardMappingProvider.PROVIDER,
424425
AndroidBinaryDataInfo.PROVIDER,
425426
AndroidBinaryNativeLibsInfo.PROVIDER,
426-
BaselineProfileProvider.PROVIDER);
427+
BaselineProfileProvider.PROVIDER,
428+
AndroidDexInfo.PROVIDER);
427429
builder.addStarlarkBootstrap(bootstrap);
428430

429431
try {

src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
6060
import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate;
6161
import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate.OutputPathMapper;
62+
import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
6263
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
6364
import com.google.devtools.build.lib.cmdline.Label;
6465
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -601,11 +602,16 @@ public static RuleConfiguredTargetBuilder createAndroidBinary(
601602
proguardOutput,
602603
postProcessingOutputMap);
603604

605+
AndroidDexInfo androidDexInfo =
606+
ruleContext.getPrerequisite("application_resources", AndroidDexInfo.PROVIDER);
607+
604608
// Compute the final DEX files by appending Java 8 legacy .dex if used.
605-
Artifact finalClassesDex;
609+
final Artifact finalClassesDex;
606610
Java8LegacyDexOutput java8LegacyDexOutput;
607611
ImmutableList<Artifact> finalShardDexZips = dexingOutput.shardDexZips;
608-
if (AndroidCommon.getAndroidConfig(ruleContext).desugarJava8Libs()
612+
if (androidDexInfo != null) {
613+
finalClassesDex = androidDexInfo.getFinalClassesDexZip();
614+
} else if (AndroidCommon.getAndroidConfig(ruleContext).desugarJava8Libs()
609615
&& dexPostprocessingOutput.classesDexZip().getFilename().endsWith(".zip")) {
610616
if (binaryJar.equals(jarToDex)) {
611617
// No shrinking: use canned Java 8 legacy .dex file
@@ -690,7 +696,11 @@ public static RuleConfiguredTargetBuilder createAndroidBinary(
690696
ApkActionsBuilder.create("apk")
691697
.setClassesDex(finalClassesDex)
692698
.addInputZip(resourceApk.getArtifact())
693-
.setJavaResourceZip(dexingOutput.javaResourceJar, resourceExtractor)
699+
.setJavaResourceZip(
700+
androidDexInfo == null
701+
? dexingOutput.javaResourceJar
702+
: androidDexInfo.getJavaResourceJar(),
703+
resourceExtractor)
694704
.addInputZips(nativeLibsAar.toList())
695705
.setNativeLibs(nativeLibs)
696706
.setUnsignedApk(unsignedApk)
@@ -979,7 +989,10 @@ public static NestedSet<Artifact> getLibraryResourceJars(RuleContext ruleContext
979989
return libraryResourceJarsBuilder.build();
980990
}
981991

982-
/** Generates an uncompressed _deploy.jar of all the runtime jars. */
992+
/**
993+
* Generates an uncompressed _deploy.jar of all the runtime jars, or creates a link to the deploy
994+
* jar created by this android_binary's android_binary_internal target if it is provided.
995+
*/
983996
public static Artifact createDeployJar(
984997
RuleContext ruleContext,
985998
JavaSemantics javaSemantics,
@@ -988,15 +1001,32 @@ public static Artifact createDeployJar(
9881001
boolean checkDesugarDeps,
9891002
Function<Artifact, Artifact> derivedJarFunction)
9901003
throws InterruptedException {
1004+
9911005
Artifact deployJar =
9921006
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_BINARY_DEPLOY_JAR);
993-
new DeployArchiveBuilder(javaSemantics, ruleContext)
994-
.setOutputJar(deployJar)
995-
.setAttributes(attributes)
996-
.addRuntimeJars(common.getRuntimeJars())
997-
.setDerivedJarFunction(derivedJarFunction)
998-
.setCheckDesugarDeps(checkDesugarDeps)
999-
.build();
1007+
1008+
AndroidDexInfo androidDexInfo =
1009+
ruleContext.getPrerequisite("application_resources", AndroidDexInfo.PROVIDER);
1010+
1011+
if (androidDexInfo != null && androidDexInfo.getDeployJar() != null) {
1012+
// Symlink to the deploy jar created by this android_binary's android_binary_internal target
1013+
// to satisfy the deploy jar implicit output of android_binary.
1014+
ruleContext.registerAction(
1015+
SymlinkAction.toArtifact(
1016+
ruleContext.getActionOwner(),
1017+
androidDexInfo.getDeployJar(), // target
1018+
deployJar, // symlink
1019+
"Symlinking Android deploy jar"));
1020+
} else {
1021+
new DeployArchiveBuilder(javaSemantics, ruleContext)
1022+
.setOutputJar(deployJar)
1023+
.setAttributes(attributes)
1024+
.addRuntimeJars(common.getRuntimeJars())
1025+
.setDerivedJarFunction(derivedJarFunction)
1026+
.setCheckDesugarDeps(checkDesugarDeps)
1027+
.build();
1028+
}
1029+
10001030
return deployJar;
10011031
}
10021032

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2023 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package com.google.devtools.build.lib.rules.android;
15+
16+
import static com.google.devtools.build.lib.rules.android.AndroidStarlarkData.fromNoneable;
17+
18+
import com.google.devtools.build.lib.actions.Artifact;
19+
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
20+
import com.google.devtools.build.lib.packages.BuiltinProvider;
21+
import com.google.devtools.build.lib.packages.NativeInfo;
22+
import com.google.devtools.build.lib.starlarkbuildapi.android.AndroidDexInfoApi;
23+
import javax.annotation.Nullable;
24+
import net.starlark.java.eval.EvalException;
25+
26+
/** A provider for Android Dex artifacts */
27+
@Immutable
28+
public class AndroidDexInfo extends NativeInfo implements AndroidDexInfoApi<Artifact> {
29+
30+
public static final String PROVIDER_NAME = "AndroidDexInfo";
31+
public static final Provider PROVIDER = new Provider();
32+
33+
private final Artifact deployJar;
34+
private final Artifact finalClassesDexZip;
35+
private final Artifact javaResourceJar;
36+
37+
public AndroidDexInfo(Artifact deployJar, Artifact finalClassesDexZip, Artifact javaResourceJar) {
38+
this.deployJar = deployJar;
39+
this.finalClassesDexZip = finalClassesDexZip;
40+
this.javaResourceJar = javaResourceJar;
41+
}
42+
43+
@Override
44+
public Provider getProvider() {
45+
return PROVIDER;
46+
}
47+
48+
@Override
49+
public Artifact getDeployJar() {
50+
return deployJar;
51+
}
52+
53+
@Override
54+
public Artifact getFinalClassesDexZip() {
55+
return finalClassesDexZip;
56+
}
57+
58+
@Override
59+
@Nullable
60+
public Artifact getJavaResourceJar() {
61+
return javaResourceJar;
62+
}
63+
64+
/** Provider for {@link AndroidDexInfo}. */
65+
public static class Provider extends BuiltinProvider<AndroidDexInfo>
66+
implements AndroidDexInfoApi.Provider<Artifact> {
67+
68+
private Provider() {
69+
super(PROVIDER_NAME, AndroidDexInfo.class);
70+
}
71+
72+
public String getName() {
73+
return PROVIDER_NAME;
74+
}
75+
76+
@Override
77+
public AndroidDexInfo createInfo(
78+
Artifact deployJar, Artifact finalClassesDexZip, Object javaResourceJar)
79+
throws EvalException {
80+
81+
return new AndroidDexInfo(
82+
deployJar, finalClassesDexZip, fromNoneable(javaResourceJar, Artifact.class));
83+
}
84+
}
85+
}

src/main/java/com/google/devtools/build/lib/starlarkbuildapi/android/AndroidBootstrap.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ public AndroidBootstrap(
6464
ProguardMappingProviderApi.Provider<?> proguardMappingProviderApiProvider,
6565
AndroidBinaryDataInfoApi.Provider<?, ?, ?, ?> androidBinaryDataInfoProvider,
6666
AndroidBinaryNativeLibsInfoApi.Provider<?> androidBinaryInternalNativeLibsInfoApiProvider,
67-
BaselineProfileProviderApi.Provider<?> baselineProfileProvider) {
67+
BaselineProfileProviderApi.Provider<?> baselineProfileProvider,
68+
AndroidDexInfoApi.Provider<?> androidDexInfoApiProvider) {
6869

6970
this.androidCommon = androidCommon;
7071
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
@@ -93,6 +94,7 @@ public AndroidBootstrap(
9394
builder.put(ProguardMappingProviderApi.NAME, proguardMappingProviderApiProvider);
9495
builder.put(AndroidBinaryDataInfoApi.NAME, androidBinaryDataInfoProvider);
9596
builder.put(BaselineProfileProviderApi.NAME, baselineProfileProvider);
97+
builder.put(AndroidDexInfoApi.NAME, androidDexInfoApiProvider);
9698
providers = builder.build();
9799
}
98100

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright 2023 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package com.google.devtools.build.lib.starlarkbuildapi.android;
15+
16+
import com.google.devtools.build.docgen.annot.StarlarkConstructor;
17+
import com.google.devtools.build.lib.starlarkbuildapi.FileApi;
18+
import com.google.devtools.build.lib.starlarkbuildapi.core.ProviderApi;
19+
import com.google.devtools.build.lib.starlarkbuildapi.core.StructApi;
20+
import javax.annotation.Nullable;
21+
import net.starlark.java.annot.Param;
22+
import net.starlark.java.annot.ParamType;
23+
import net.starlark.java.annot.StarlarkBuiltin;
24+
import net.starlark.java.annot.StarlarkMethod;
25+
import net.starlark.java.eval.EvalException;
26+
import net.starlark.java.eval.NoneType;
27+
28+
/** An Info that can provides dex artifacts. */
29+
@StarlarkBuiltin(
30+
name = "AndroidDexInfo",
31+
doc =
32+
"Do not use this module. It is intended for migration purposes only. If you depend on it, "
33+
+ "you will be broken when it is removed.",
34+
documented = false)
35+
public interface AndroidDexInfoApi<FileT extends FileApi> extends StructApi {
36+
37+
/** Name of this info object. */
38+
String NAME = "AndroidDexInfo";
39+
40+
@StarlarkMethod(
41+
name = "deploy_jar",
42+
doc = "The deploy jar.",
43+
documented = false,
44+
structField = true)
45+
FileT getDeployJar();
46+
47+
@StarlarkMethod(
48+
name = "final_classes_dex_zip",
49+
doc = "The zip file containing the final dex classes.",
50+
documented = false,
51+
structField = true)
52+
FileT getFinalClassesDexZip();
53+
54+
@Nullable
55+
@StarlarkMethod(
56+
name = "java_resource_jar",
57+
doc = "The final Java resource jar.",
58+
documented = false,
59+
structField = true,
60+
allowReturnNones = true)
61+
FileT getJavaResourceJar();
62+
63+
/** Provider for {@link AndroidDexInfoApi}. */
64+
@StarlarkBuiltin(
65+
name = "Provider",
66+
doc =
67+
"Do not use this module. It is intended for migration purposes only. If you depend on "
68+
+ "it, you will be broken when it is removed.",
69+
documented = false)
70+
interface Provider<FileT extends FileApi> extends ProviderApi {
71+
72+
@StarlarkMethod(
73+
name = NAME,
74+
doc = "The <code>AndroidDexInfo</code> constructor.",
75+
documented = false,
76+
parameters = {
77+
@Param(
78+
name = "deploy_jar",
79+
allowedTypes = {
80+
@ParamType(type = FileApi.class),
81+
},
82+
named = true,
83+
doc = "The \"_deploy\" jar suitable for deployment."),
84+
@Param(
85+
name = "final_classes_dex_zip",
86+
allowedTypes = {
87+
@ParamType(type = FileApi.class),
88+
},
89+
named = true,
90+
doc = "The zip file containing the final dex classes."),
91+
@Param(
92+
name = "java_resource_jar",
93+
allowedTypes = {
94+
@ParamType(type = FileApi.class),
95+
@ParamType(type = NoneType.class),
96+
},
97+
named = true,
98+
doc = "The final Java resource jar."),
99+
},
100+
selfCall = true)
101+
@StarlarkConstructor
102+
AndroidDexInfoApi<FileT> createInfo(
103+
FileT deployJar, FileT finalClassesDexZip, Object javaResourceJar) throws EvalException;
104+
}
105+
}

src/test/java/com/google/devtools/build/lib/rules/android/AndroidBuildViewTestCase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ protected Artifact getFinalUnsignedApk(ConfiguredTarget target) {
189189
target.getProvider(FileProvider.class).getFilesToBuild(), "_unsigned.apk");
190190
}
191191

192+
protected Artifact getDeployJar(ConfiguredTarget target) {
193+
return getFirstArtifactEndingWith(
194+
target.getProvider(FileProvider.class).getFilesToBuild(), "_deploy.jar");
195+
}
196+
192197
protected Artifact getResourceApk(ConfiguredTarget target) {
193198
Artifact resourceApk =
194199
getFirstArtifactEndingWith(

0 commit comments

Comments
 (0)