diff options
author | 2016-08-10 22:31:57 +0000 | |
---|---|---|
committer | 2016-08-11 09:17:58 +0000 | |
commit | b96f74f18d132245d4a8029164b981c04d49ded2 (patch) | |
tree | 5d2eadb58257d0b4ad57fe1817eb4f442f2412b6 | |
parent | fb1d53df557ee10f13ed4299f0688ea81cfe4fb6 (diff) |
Sets SONAME on shared objects in Android binaries.
Adds a linker flag to set the internal DT_SONAME. This fixes #1578 for
SDK 24 and removes the warnings for previous SDKs. There is no need to
set the linker flag for android_librarys that depend on native code,
because the linker flag will be set by the android_binarys that depend
on that android_library.
Testing is done via `readelf` executable that is shipped with the NDK.
--
Change-Id: I16fdfe6522c8694ce51554289122bf035a61d9ec
Reviewed-on: https://bazel-review.googlesource.com/#/c/4302/
MOS_MIGRATED_REVID=129920256
3 files changed, 32 insertions, 9 deletions
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 688c5c5dd6..1000216366 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 @@ -861,22 +861,25 @@ public class AndroidCommon { } public CcLinkParamsStore getCcLinkParamsStore() { - return getCcLinkParamsStore(javaCommon.targetsTreatedAsDeps(ClasspathType.BOTH)); + return getCcLinkParamsStore( + javaCommon.targetsTreatedAsDeps(ClasspathType.BOTH), ImmutableList.<String>of()); } public static CcLinkParamsStore getCcLinkParamsStore( - final Iterable<? extends TransitiveInfoCollection> deps) { + final Iterable<? extends TransitiveInfoCollection> deps, final Collection<String> linkOpts) { return new CcLinkParamsStore() { @Override - protected void collect(CcLinkParams.Builder builder, boolean linkingStatically, - boolean linkShared) { - builder.addTransitiveTargets(deps, + protected void collect( + CcLinkParams.Builder builder, boolean linkingStatically, boolean linkShared) { + builder.addTransitiveTargets( + deps, // Link in Java-specific C++ code in the transitive closure JavaCcLinkParamsProvider.TO_LINK_PARAMS, // Link in Android-specific C++ code (e.g., android_libraries) in the transitive closure AndroidCcLinkParamsProvider.TO_LINK_PARAMS, // Link in non-language-specific C++ code in the transitive closure CcLinkParamsProvider.TO_LINK_PARAMS); + builder.addLinkOpts(linkOpts); } }; } 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 46446d2f31..421e8f2f53 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 @@ -34,14 +34,12 @@ 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; - import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; - import javax.annotation.Nullable; /** Represents the collection of native libraries (.so) to be installed in the APK. */ @@ -71,8 +69,11 @@ public final class NativeLibs { Map<String, Iterable<Artifact>> result = new LinkedHashMap<>(); for (Map.Entry<String, Collection<TransitiveInfoCollection>> entry : depsByArchitecture.asMap().entrySet()) { - CcLinkParams linkParams = AndroidCommon.getCcLinkParamsStore(entry.getValue()) - .get(/* linkingStatically */ true, /* linkShared */ true); + CcLinkParams linkParams = + AndroidCommon.getCcLinkParamsStore( + entry.getValue(), + ImmutableList.of("-Wl,-soname=lib" + ruleContext.getLabel().getName())) + .get(/* linkingStatically */ true, /* linkShared */ true); Artifact nativeDepsLibrary = NativeDepsHelper.maybeCreateAndroidNativeDepsAction( ruleContext, linkParams, configurationMap.get(entry.getKey()), diff --git a/src/test/shell/bazel/android/android_integration_test.sh b/src/test/shell/bazel/android/android_integration_test.sh index 38162a345e..e4b6d81767 100755 --- a/src/test/shell/bazel/android/android_integration_test.sh +++ b/src/test/shell/bazel/android/android_integration_test.sh @@ -159,6 +159,23 @@ function check_num_sos() { assert_equals "11" "$num_sos" } +function check_soname() { + # For an android_binary with name foo, readelf output format is + # Tag Type Name/Value + # 0x00000010 (SONAME) Library soname: [libfoo] + # + # If -Wl,soname= is not set, then SONAME will not appear in the output. + # + # readelf is a Linux utility and not available on Mac by default. The NDK + # includes readelf however the path is difference for Mac vs Linux, hence the + # star. + readelf="${TEST_SRCDIR}/androidndk/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/*/bin/arm-linux-androideabi-readelf" + soname=$($readelf -d bazel-bin/java/bazel/_dx/bin/native_symlinks/x86/libbin.so \ + | grep SONAME \ + | awk '{print substr($5,2,length($5)-2)}') + assert_equals "libbin" "$soname" +} + function test_sdk_library_deps() { create_new_workspace setup_android_support @@ -183,6 +200,7 @@ function test_android_binary() { bazel build -s //java/bazel:bin --fat_apk_cpu="$cpus" || fail "build failed" check_num_sos + check_soname } function test_android_binary_clang() { @@ -202,6 +220,7 @@ function test_android_binary_clang() { --android_compiler=clang3.8 \ || fail "build failed" check_num_sos + check_soname } # ndk r10 and earlier |