Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.3.0] Add a new provider for passing dex related artifacts in android_binary #18899

Merged
merged 3 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import com.google.devtools.build.lib.rules.android.AndroidDeviceBrokerInfo;
import com.google.devtools.build.lib.rules.android.AndroidDeviceRule;
import com.google.devtools.build.lib.rules.android.AndroidDeviceScriptFixtureRule;
import com.google.devtools.build.lib.rules.android.AndroidDexInfo;
import com.google.devtools.build.lib.rules.android.AndroidFeatureFlagSetProvider;
import com.google.devtools.build.lib.rules.android.AndroidHostServiceFixtureRule;
import com.google.devtools.build.lib.rules.android.AndroidIdeInfoProvider;
Expand Down Expand Up @@ -423,7 +424,8 @@ public void init(ConfiguredRuleClassProvider.Builder builder) {
ProguardMappingProvider.PROVIDER,
AndroidBinaryDataInfo.PROVIDER,
AndroidBinaryNativeLibsInfo.PROVIDER,
BaselineProfileProvider.PROVIDER);
BaselineProfileProvider.PROVIDER,
AndroidDexInfo.PROVIDER);
builder.addStarlarkBootstrap(bootstrap);

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate;
import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate.OutputPathMapper;
import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
Expand Down Expand Up @@ -601,11 +602,16 @@ public static RuleConfiguredTargetBuilder createAndroidBinary(
proguardOutput,
postProcessingOutputMap);

AndroidDexInfo androidDexInfo =
ruleContext.getPrerequisite("application_resources", AndroidDexInfo.PROVIDER);

// Compute the final DEX files by appending Java 8 legacy .dex if used.
Artifact finalClassesDex;
final Artifact finalClassesDex;
Java8LegacyDexOutput java8LegacyDexOutput;
ImmutableList<Artifact> finalShardDexZips = dexingOutput.shardDexZips;
if (AndroidCommon.getAndroidConfig(ruleContext).desugarJava8Libs()
if (androidDexInfo != null) {
finalClassesDex = androidDexInfo.getFinalClassesDexZip();
} else if (AndroidCommon.getAndroidConfig(ruleContext).desugarJava8Libs()
&& dexPostprocessingOutput.classesDexZip().getFilename().endsWith(".zip")) {
if (binaryJar.equals(jarToDex)) {
// No shrinking: use canned Java 8 legacy .dex file
Expand Down Expand Up @@ -690,7 +696,11 @@ public static RuleConfiguredTargetBuilder createAndroidBinary(
ApkActionsBuilder.create("apk")
.setClassesDex(finalClassesDex)
.addInputZip(resourceApk.getArtifact())
.setJavaResourceZip(dexingOutput.javaResourceJar, resourceExtractor)
.setJavaResourceZip(
androidDexInfo == null
? dexingOutput.javaResourceJar
: androidDexInfo.getJavaResourceJar(),
resourceExtractor)
.addInputZips(nativeLibsAar.toList())
.setNativeLibs(nativeLibs)
.setUnsignedApk(unsignedApk)
Expand Down Expand Up @@ -979,7 +989,10 @@ public static NestedSet<Artifact> getLibraryResourceJars(RuleContext ruleContext
return libraryResourceJarsBuilder.build();
}

/** Generates an uncompressed _deploy.jar of all the runtime jars. */
/**
* Generates an uncompressed _deploy.jar of all the runtime jars, or creates a link to the deploy
* jar created by this android_binary's android_binary_internal target if it is provided.
*/
public static Artifact createDeployJar(
RuleContext ruleContext,
JavaSemantics javaSemantics,
Expand All @@ -988,15 +1001,32 @@ public static Artifact createDeployJar(
boolean checkDesugarDeps,
Function<Artifact, Artifact> derivedJarFunction)
throws InterruptedException {

Artifact deployJar =
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_BINARY_DEPLOY_JAR);
new DeployArchiveBuilder(javaSemantics, ruleContext)
.setOutputJar(deployJar)
.setAttributes(attributes)
.addRuntimeJars(common.getRuntimeJars())
.setDerivedJarFunction(derivedJarFunction)
.setCheckDesugarDeps(checkDesugarDeps)
.build();

AndroidDexInfo androidDexInfo =
ruleContext.getPrerequisite("application_resources", AndroidDexInfo.PROVIDER);

if (androidDexInfo != null && androidDexInfo.getDeployJar() != null) {
// Symlink to the deploy jar created by this android_binary's android_binary_internal target
// to satisfy the deploy jar implicit output of android_binary.
ruleContext.registerAction(
SymlinkAction.toArtifact(
ruleContext.getActionOwner(),
androidDexInfo.getDeployJar(), // target
deployJar, // symlink
"Symlinking Android deploy jar"));
} else {
new DeployArchiveBuilder(javaSemantics, ruleContext)
.setOutputJar(deployJar)
.setAttributes(attributes)
.addRuntimeJars(common.getRuntimeJars())
.setDerivedJarFunction(derivedJarFunction)
.setCheckDesugarDeps(checkDesugarDeps)
.build();
}

return deployJar;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2023 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.rules.android;

import static com.google.devtools.build.lib.rules.android.AndroidStarlarkData.fromNoneable;

import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.starlarkbuildapi.android.AndroidDexInfoApi;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;

/** A provider for Android Dex artifacts */
@Immutable
public class AndroidDexInfo extends NativeInfo implements AndroidDexInfoApi<Artifact> {

public static final String PROVIDER_NAME = "AndroidDexInfo";
public static final Provider PROVIDER = new Provider();

private final Artifact deployJar;
private final Artifact finalClassesDexZip;
private final Artifact javaResourceJar;

public AndroidDexInfo(Artifact deployJar, Artifact finalClassesDexZip, Artifact javaResourceJar) {
this.deployJar = deployJar;
this.finalClassesDexZip = finalClassesDexZip;
this.javaResourceJar = javaResourceJar;
}

@Override
public Provider getProvider() {
return PROVIDER;
}

@Override
public Artifact getDeployJar() {
return deployJar;
}

@Override
public Artifact getFinalClassesDexZip() {
return finalClassesDexZip;
}

@Override
@Nullable
public Artifact getJavaResourceJar() {
return javaResourceJar;
}

/** Provider for {@link AndroidDexInfo}. */
public static class Provider extends BuiltinProvider<AndroidDexInfo>
implements AndroidDexInfoApi.Provider<Artifact> {

private Provider() {
super(PROVIDER_NAME, AndroidDexInfo.class);
}

public String getName() {
return PROVIDER_NAME;
}

@Override
public AndroidDexInfo createInfo(
Artifact deployJar, Artifact finalClassesDexZip, Object javaResourceJar)
throws EvalException {

return new AndroidDexInfo(
deployJar, finalClassesDexZip, fromNoneable(javaResourceJar, Artifact.class));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public AndroidBootstrap(
ProguardMappingProviderApi.Provider<?> proguardMappingProviderApiProvider,
AndroidBinaryDataInfoApi.Provider<?, ?, ?, ?> androidBinaryDataInfoProvider,
AndroidBinaryNativeLibsInfoApi.Provider<?> androidBinaryInternalNativeLibsInfoApiProvider,
BaselineProfileProviderApi.Provider<?> baselineProfileProvider) {
BaselineProfileProviderApi.Provider<?> baselineProfileProvider,
AndroidDexInfoApi.Provider<?> androidDexInfoApiProvider) {

this.androidCommon = androidCommon;
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
Expand Down Expand Up @@ -93,6 +94,7 @@ public AndroidBootstrap(
builder.put(ProguardMappingProviderApi.NAME, proguardMappingProviderApiProvider);
builder.put(AndroidBinaryDataInfoApi.NAME, androidBinaryDataInfoProvider);
builder.put(BaselineProfileProviderApi.NAME, baselineProfileProvider);
builder.put(AndroidDexInfoApi.NAME, androidDexInfoApiProvider);
providers = builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2023 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.starlarkbuildapi.android;

import com.google.devtools.build.docgen.annot.StarlarkConstructor;
import com.google.devtools.build.lib.starlarkbuildapi.FileApi;
import com.google.devtools.build.lib.starlarkbuildapi.core.ProviderApi;
import com.google.devtools.build.lib.starlarkbuildapi.core.StructApi;
import javax.annotation.Nullable;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.ParamType;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.NoneType;

/** An Info that can provides dex artifacts. */
@StarlarkBuiltin(
name = "AndroidDexInfo",
doc =
"Do not use this module. It is intended for migration purposes only. If you depend on it, "
+ "you will be broken when it is removed.",
documented = false)
public interface AndroidDexInfoApi<FileT extends FileApi> extends StructApi {

/** Name of this info object. */
String NAME = "AndroidDexInfo";

@StarlarkMethod(
name = "deploy_jar",
doc = "The deploy jar.",
documented = false,
structField = true)
FileT getDeployJar();

@StarlarkMethod(
name = "final_classes_dex_zip",
doc = "The zip file containing the final dex classes.",
documented = false,
structField = true)
FileT getFinalClassesDexZip();

@Nullable
@StarlarkMethod(
name = "java_resource_jar",
doc = "The final Java resource jar.",
documented = false,
structField = true,
allowReturnNones = true)
FileT getJavaResourceJar();

/** Provider for {@link AndroidDexInfoApi}. */
@StarlarkBuiltin(
name = "Provider",
doc =
"Do not use this module. It is intended for migration purposes only. If you depend on "
+ "it, you will be broken when it is removed.",
documented = false)
interface Provider<FileT extends FileApi> extends ProviderApi {

@StarlarkMethod(
name = NAME,
doc = "The <code>AndroidDexInfo</code> constructor.",
documented = false,
parameters = {
@Param(
name = "deploy_jar",
allowedTypes = {
@ParamType(type = FileApi.class),
},
named = true,
doc = "The \"_deploy\" jar suitable for deployment."),
@Param(
name = "final_classes_dex_zip",
allowedTypes = {
@ParamType(type = FileApi.class),
},
named = true,
doc = "The zip file containing the final dex classes."),
@Param(
name = "java_resource_jar",
allowedTypes = {
@ParamType(type = FileApi.class),
@ParamType(type = NoneType.class),
},
named = true,
doc = "The final Java resource jar."),
},
selfCall = true)
@StarlarkConstructor
AndroidDexInfoApi<FileT> createInfo(
FileT deployJar, FileT finalClassesDexZip, Object javaResourceJar) throws EvalException;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ protected Artifact getFinalUnsignedApk(ConfiguredTarget target) {
target.getProvider(FileProvider.class).getFilesToBuild(), "_unsigned.apk");
}

protected Artifact getDeployJar(ConfiguredTarget target) {
return getFirstArtifactEndingWith(
target.getProvider(FileProvider.class).getFilesToBuild(), "_deploy.jar");
}

protected Artifact getResourceApk(ConfiguredTarget target) {
Artifact resourceApk =
getFirstArtifactEndingWith(
Expand Down