diff options
author | 2015-08-24 15:21:45 +0000 | |
---|---|---|
committer | 2015-08-25 07:40:32 +0000 | |
commit | 027c8822bd397941cb557f6b0e01b9a812161309 (patch) | |
tree | 367ebbf921dfb7d564c43915adc7f9c9d4ce9f32 /src/main/java | |
parent | 7bda87e80adf980a2b0c50da66e3f9fa17c27605 (diff) |
Copies shared object dependencies when building Android native binaries.
Previously, shared objects in the transitive closure of an Android binary would be linked
in, but not be sent to the apkbuilder. This sends all the shared objects used for linking
to join the other native libraries in the APK, so they will be loadable when the main
library created by the link step is loaded.
Fixes #357.
--
MOS_MIGRATED_REVID=101365491
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java | 26 |
1 files changed, 21 insertions, 5 deletions
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 1b5f1c9f9e..35ae4b80b5 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.config.BuildConfiguration; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.rules.cpp.CcLinkParams; import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; +import com.google.devtools.build.lib.rules.cpp.CppFileTypes; import com.google.devtools.build.lib.rules.cpp.LinkerInput; import com.google.devtools.build.lib.rules.nativedeps.NativeDepsHelper; import com.google.devtools.build.lib.vfs.PathFragment; @@ -53,7 +54,7 @@ public final class NativeLibs { depsByArchitecture.asMap().entrySet()) { NestedSet<LinkerInput> nativeLibraries = AndroidCommon.collectTransitiveNativeLibraries(entry.getValue()); - builder.put(entry.getKey(), checkUniqueBaseNames(ruleContext, nativeLibraries)); + builder.put(entry.getKey(), filterUniqueSharedLibraries(ruleContext, nativeLibraries)); } return new NativeLibs(builder.build(), null); } @@ -69,11 +70,20 @@ public final class NativeLibs { depsByArchitecture.asMap().entrySet()) { CcLinkParams linkParams = AndroidCommon.getCcLinkParamsStore(entry.getValue()) .get(/* linkingStatically */ true, /* linkShared */ true); + Artifact nativeDepsLibrary = NativeDepsHelper.maybeCreateAndroidNativeDepsAction( ruleContext, linkParams, configurationMap.get(entry.getKey()), toolchainMap.get(entry.getKey())); + + ImmutableList.Builder<Artifact> librariesBuilder = ImmutableList.builder(); + librariesBuilder.addAll(filterUniqueSharedLibraries(ruleContext, linkParams.getLibraries())); if (nativeDepsLibrary != null) { - result.put(entry.getKey(), ImmutableList.of(nativeDepsLibrary)); + librariesBuilder.add(nativeDepsLibrary); + } + ImmutableList<Artifact> libraries = librariesBuilder.build(); + + if (!libraries.isEmpty()) { + result.put(entry.getKey(), libraries); } } if (result.isEmpty()) { @@ -156,11 +166,17 @@ public final class NativeLibs { return nativeLibsName; } - private static Iterable<Artifact> checkUniqueBaseNames( - RuleContext ruleContext, NestedSet<LinkerInput> libraries) { + private static Iterable<Artifact> filterUniqueSharedLibraries( + RuleContext ruleContext, NestedSet<? extends LinkerInput> libraries) { Map<String, Artifact> basenames = new HashMap<>(); Set<Artifact> artifacts = new HashSet<>(); for (LinkerInput linkerInput : libraries) { + String name = linkerInput.getArtifact().getFilename(); + if (!(CppFileTypes.SHARED_LIBRARY.matches(name) + || CppFileTypes.VERSIONED_SHARED_LIBRARY.matches(name))) { + // This is not a shared library and will not be loaded by Android, so skip it. + continue; + } Artifact artifact = linkerInput.getOriginalLibraryArtifact(); if (!artifacts.add(artifact)) { // We have already reached this library, e.g., through a different solib symlink. @@ -169,7 +185,7 @@ public final class NativeLibs { String basename = artifact.getExecPath().getBaseName(); Artifact oldArtifact = basenames.put(basename, artifact); if (oldArtifact != null) { - // Without linking, there may be name collisions in the libraries which were provided, so + // There may be name collisions in the libraries which were provided, so // check for this at this step. ruleContext.ruleError("Each library in the transitive closure must have a unique " + "basename, but two libraries had the basename '" + basename + "': " |