Expose the native libs of the android_binary rule to skylark.
RELNOTES: none
PiperOrigin-RevId: 153223511
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index 52c1b52..7fbe3a2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -799,7 +799,13 @@
debugKeystore);
androidCommon.addTransitiveInfoProviders(
- builder, androidSemantics, null /* aar */, resourceApk, zipAlignedApk, apksUnderTest);
+ builder,
+ androidSemantics,
+ null /* aar */,
+ resourceApk,
+ zipAlignedApk,
+ apksUnderTest,
+ nativeLibs);
androidSemantics.addTransitiveInfoProviders(builder, ruleContext, javaCommon, androidCommon);
if (proguardOutput.getMapping() != null) {
@@ -909,7 +915,7 @@
}
if (ruleContext.getFragment(AndroidConfiguration.class).useIncrementalNativeLibs()) {
- for (Map.Entry<String, Iterable<Artifact>> arch : nativeLibs.getMap().entrySet()) {
+ for (Map.Entry<String, NestedSet<Artifact>> arch : nativeLibs.getMap().entrySet()) {
for (Artifact lib : arch.getValue()) {
builder
.addArgument("--native_lib")
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
index ab6878c..279f252 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
@@ -233,13 +233,15 @@
Artifact aar,
ResourceApk resourceApk,
Artifact zipAlignedApk,
- Iterable<Artifact> apksUnderTest) {
+ Iterable<Artifact> apksUnderTest,
+ NativeLibs nativeLibs) {
AndroidIdeInfoProvider.Builder ideInfoProviderBuilder =
new AndroidIdeInfoProvider.Builder()
.setIdlClassJar(idlHelper.getIdlClassJar())
.setIdlSourceJar(idlHelper.getIdlSourceJar())
.setResourceJar(resourceJar)
.setAar(aar)
+ .setNativeLibs(nativeLibs.getMap())
.addIdlImportRoot(idlHelper.getIdlImportRoot())
.addIdlParcelables(idlHelper.getIdlParcelables())
.addIdlSrcs(idlHelper.getIdlSources())
@@ -703,7 +705,8 @@
Artifact aar,
ResourceApk resourceApk,
Artifact zipAlignedApk,
- Iterable<Artifact> apksUnderTest) {
+ Iterable<Artifact> apksUnderTest,
+ NativeLibs nativeLibs) {
idlHelper.addTransitiveInfoProviders(builder, classJar, manifestProtoOutput);
@@ -757,7 +760,8 @@
aar,
resourceApk,
zipAlignedApk,
- apksUnderTest))
+ apksUnderTest,
+ nativeLibs))
.add(JavaCompilationArgsProvider.class, compilationArgsProvider)
.addSkylarkTransitiveInfo(AndroidSkylarkApiProvider.NAME, new AndroidSkylarkApiProvider())
.addOutputGroup(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdeInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdeInfoProvider.java
index c73eb96..cc5b9bb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdeInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdeInfoProvider.java
@@ -16,21 +16,22 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Root;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
-
import java.util.Collection;
import java.util.LinkedHashSet;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
-
import javax.annotation.Nullable;
/**
@@ -140,6 +141,7 @@
private final Set<Artifact> apksUnderTest = new LinkedHashSet<>();
private boolean definesAndroidResources;
private Artifact aar = null;
+ private Map<String, NestedSet<Artifact>> nativeLibs = null;
public AndroidIdeInfoProvider build() {
return new AndroidIdeInfoProvider(
@@ -158,7 +160,10 @@
ImmutableList.copyOf(idlDirs),
ImmutableList.copyOf(idlSrcs),
ImmutableList.copyOf(idlGeneratedJavaFiles),
- ImmutableList.copyOf(apksUnderTest));
+ ImmutableList.copyOf(apksUnderTest),
+ nativeLibs != null
+ ? ImmutableMap.copyOf(nativeLibs)
+ : ImmutableMap.<String, NestedSet<Artifact>>of());
}
public Builder setJavaPackage(String javaPackage) {
@@ -211,6 +216,12 @@
return this;
}
+ public Builder setNativeLibs(Map<String, NestedSet<Artifact>> nativeLibs) {
+ this.nativeLibs = nativeLibs;
+ return this;
+ }
+
+
public Builder addIdlImportRoot(String idlImportRoot) {
this.idlImportRoot = idlImportRoot;
return this;
@@ -293,7 +304,6 @@
Iterables.addAll(apksUnderTest, apks);
return this;
}
-
}
private final String javaPackage;
@@ -312,6 +322,7 @@
private final ImmutableCollection<Artifact> idlSrcs;
private final ImmutableCollection<Artifact> idlGeneratedJavaFiles;
private final ImmutableCollection<Artifact> apksUnderTest;
+ private final ImmutableMap<String, NestedSet<Artifact>> nativeLibs;
AndroidIdeInfoProvider(
String javaPackage,
@@ -329,7 +340,8 @@
ImmutableCollection<SourceDirectory> idlImports,
ImmutableCollection<Artifact> idlSrcs,
ImmutableCollection<Artifact> idlGeneratedJavaFiles,
- ImmutableCollection<Artifact> apksUnderTest) {
+ ImmutableCollection<Artifact> apksUnderTest,
+ ImmutableMap<String, NestedSet<Artifact>> nativeLibs) {
this.javaPackage = javaPackage;
this.idlImportRoot = idlImportRoot;
this.manifest = manifest;
@@ -346,6 +358,7 @@
this.idlSrcs = idlSrcs;
this.idlGeneratedJavaFiles = idlGeneratedJavaFiles;
this.apksUnderTest = apksUnderTest;
+ this.nativeLibs = nativeLibs;
}
/** Returns java package for this target. */
@@ -433,4 +446,9 @@
public ImmutableCollection<Artifact> getApksUnderTest() {
return apksUnderTest;
}
+
+ /** A map, keyed on architecture, of the native libs for the app, if any. */
+ public ImmutableMap<String, NestedSet<Artifact>> getNativeLibs() {
+ return nativeLibs;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
index 5f0da5f..0648e10 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
@@ -195,8 +195,14 @@
.build(ruleContext);
RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext);
- androidCommon.addTransitiveInfoProviders(builder, androidSemantics, aarOut,
- resourceApk, null, ImmutableList.<Artifact>of());
+ androidCommon.addTransitiveInfoProviders(
+ builder,
+ androidSemantics,
+ aarOut,
+ resourceApk,
+ null,
+ ImmutableList.<Artifact>of(),
+ NativeLibs.EMPTY);
androidSemantics.addTransitiveInfoProviders(builder, ruleContext, javaCommon, androidCommon);
NestedSetBuilder<Artifact> transitiveResourcesJars = collectTransitiveResourceJars(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkApiProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkApiProvider.java
index 4ca0f5b..90d10291 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkApiProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkApiProvider.java
@@ -16,6 +16,7 @@
import com.google.common.base.Function;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -95,6 +96,18 @@
}
@SkylarkCallable(
+ name = "native_libs",
+ structField = true,
+ doc =
+ "Returns the native libraries as a map of the libraries' architecture as a String to a "
+ + "set of the native library artifacts, or the empty map if there are no native "
+ + "libraries."
+ )
+ public ImmutableMap<String, NestedSet<Artifact>> getNativeLibs() {
+ return getIdeInfoProvider().getNativeLibs();
+ }
+
+ @SkylarkCallable(
name = "apks_under_test",
structField = true,
allowReturnNones = true,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApkManifestAction.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApkManifestAction.java
index e8753ce..4ab7f74 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ApkManifestAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApkManifestAction.java
@@ -23,13 +23,13 @@
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction;
import com.google.devtools.build.lib.collect.CollectionUtils;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.rules.android.apkmanifest.ApkManifestOuterClass;
import com.google.devtools.build.lib.rules.android.apkmanifest.ApkManifestOuterClass.ApkManifest;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.protobuf.ByteString;
import com.google.protobuf.TextFormat;
-
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
@@ -59,7 +59,6 @@
.add(sdk.getResourceExtractor().getExecutable())
.add(sdk.getShrinkedAndroidJar())
.add(sdk.getZipalign().getExecutable())
-
.addAll(jars)
.add(resourceApk.getArtifact())
.add(resourceApk.getManifest())
@@ -185,7 +184,7 @@
manifestBuilder.setResourceApk(makeArtifactProto(resourceApk.getArtifact()));
manifestBuilder.setAndroidManifest(makeArtifactProto(resourceApk.getManifest()));
- for (Map.Entry<String, Iterable<Artifact>> nativeLib : nativeLibs.getMap().entrySet()) {
+ for (Map.Entry<String, NestedSet<Artifact>> nativeLib : nativeLibs.getMap().entrySet()) {
if (!Iterables.isEmpty(nativeLib.getValue())) {
manifestBuilder.addNativeLibBuilder()
.setArch(nativeLib.getKey())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java b/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
index 48783e6..32a7c72 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
@@ -28,6 +28,7 @@
import com.google.devtools.build.lib.analysis.actions.SymlinkTreeAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.rules.cpp.CcLinkParams;
import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
@@ -48,7 +49,7 @@
@Immutable
public final class NativeLibs {
public static final NativeLibs EMPTY =
- new NativeLibs(ImmutableMap.<String, Iterable<Artifact>>of(), null);
+ new NativeLibs(ImmutableMap.<String, NestedSet<Artifact>>of(), null);
public static NativeLibs fromLinkedNativeDeps(
RuleContext ruleContext,
@@ -57,7 +58,7 @@
Map<String, CcToolchainProvider> toolchainMap,
Map<String, BuildConfiguration> configurationMap)
throws InterruptedException {
- Map<String, Iterable<Artifact>> result = new LinkedHashMap<>();
+ Map<String, NestedSet<Artifact>> result = new LinkedHashMap<>();
String nativeDepsLibraryBasename = null;
for (Map.Entry<String, Collection<TransitiveInfoCollection>> entry :
depsByArchitecture.asMap().entrySet()) {
@@ -74,14 +75,14 @@
configurationMap.get(entry.getKey()),
toolchainMap.get(entry.getKey()));
- ImmutableList.Builder<Artifact> librariesBuilder = ImmutableList.builder();
+ NestedSetBuilder<Artifact> librariesBuilder = NestedSetBuilder.stableOrder();
if (nativeDepsLibrary != null) {
librariesBuilder.add(nativeDepsLibrary);
nativeDepsLibraryBasename = nativeDepsLibrary.getExecPath().getBaseName();
}
librariesBuilder.addAll(
filterUniqueSharedLibraries(ruleContext, nativeDepsLibrary, linkParams.getLibraries()));
- ImmutableList<Artifact> libraries = librariesBuilder.build();
+ NestedSet<Artifact> libraries = librariesBuilder.build();
if (!libraries.isEmpty()) {
result.put(entry.getKey(), libraries);
@@ -106,21 +107,21 @@
}
// Map from architecture (CPU folder to place the library in) to libraries for that CPU
- private final ImmutableMap<String, Iterable<Artifact>> nativeLibs;
+ private final ImmutableMap<String, NestedSet<Artifact>> nativeLibs;
@Nullable private final Artifact nativeLibsName;
@VisibleForTesting
- NativeLibs(ImmutableMap<String, Iterable<Artifact>> nativeLibs,
- @Nullable Artifact nativeLibsName) {
+ NativeLibs(
+ ImmutableMap<String, NestedSet<Artifact>> nativeLibs, @Nullable Artifact nativeLibsName) {
this.nativeLibs = nativeLibs;
this.nativeLibsName = nativeLibsName;
}
/**
* Returns a map from the name of the architecture (CPU folder to place the library in) to the
- * set of libraries for that architecture.
+ * nested set of libraries for that architecture.
*/
- public Map<String, Iterable<Artifact>> getMap() {
+ public Map<String, NestedSet<Artifact>> getMap() {
return nativeLibs;
}
@@ -136,7 +137,7 @@
public Pair<Artifact, Runfiles> createApkBuilderSymlinks(RuleContext ruleContext) {
Map<PathFragment, Artifact> symlinks = new LinkedHashMap<>();
- for (Map.Entry<String, Iterable<Artifact>> entry : nativeLibs.entrySet()) {
+ for (Map.Entry<String, NestedSet<Artifact>> entry : nativeLibs.entrySet()) {
String arch = entry.getKey();
for (Artifact lib : entry.getValue()) {
symlinks.put(PathFragment.create(arch + "/" + lib.getExecPath().getBaseName()), lib);
@@ -216,7 +217,7 @@
+ artifact.prettyPrint()
+ " and "
+ oldArtifact.prettyPrint()
- + ((oldArtifact == linkedLibrary)
+ + ((oldArtifact.equals(linkedLibrary))
? " (the library compiled for this target)"
: ""));
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/ApkManifestActionTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/ApkManifestActionTest.java
index 392c9e6..63d0589 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/android/ApkManifestActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/ApkManifestActionTest.java
@@ -24,6 +24,8 @@
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.util.FileSystems;
@@ -87,11 +89,16 @@
null, // mainDexProguardConfig
false /* legacy */);
- NativeLibs nativeLibs = new NativeLibs(
- ImmutableMap.<String, Iterable<Artifact>>of(
- "x86", ImmutableList.of(createArtifact("/workspace/java/test/x86.so")),
- "arm", ImmutableList.of(createArtifact("/workspace/java/test/arm.so"))),
- null /* nativeLibsName */);
+ NativeLibs nativeLibs =
+ new NativeLibs(
+ ImmutableMap.<String, NestedSet<Artifact>>of(
+ "x86", NestedSetBuilder.<Artifact>stableOrder()
+ .add(createArtifact("/workspace/java/test/x86.so"))
+ .build(),
+ "arm", NestedSetBuilder.<Artifact>stableOrder()
+ .add(createArtifact("/workspace/java/test/arm.so"))
+ .build()),
+ null /* nativeLibsName */);
Artifact debugKeystore = createArtifact("/workspace/tools/android/debug_keystore");