1

I am doing an Android Open Source Project build (AOSP) not an Android Studio build.

I have an AAR file that contains several .so shared object native libraries.

Previously, in an Android.mk makefile I could extract them to a folder, and include them as LOCAL_PREBUILT_JNI_LIBS like this:

include $(CLEAR_VARS)    
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PREBUILT_JNI_LIBS := $(addprefix $(AAR_RELATIVE_EXTRACT_PATH)/,$(AAR_JNI_SO_FILE_LIST))
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
LOCAL_STATIC_JAVA_AAR_LIBRARIES := $(AAR_ALIAS)
LOCAL_PRIVATE_PLATFORM_APIS := true
include $(BUILD_PACKAGE)

In Android 15, this Makefile is giving me a transitive dependency error, and rather than fix it, I'd rather migrate it to a Blueprint file.

We had been unable to accomplish this same result using an Android.bp file through Android 13 since anything we tried lost the .so files. Now in Soong for Android 15, I see we have a tempting new flag in android_library_import called extract_jni which the Soong Modules Reference describes as

extract_jni bool, If true, extract JNI libs from AAR archive. These libs will be accessible to android_app modules and will be passed transitively through android_libraries to an android_app. TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion

This is exactly what I'm trying to do! I tried using this in a Android.bp as:

android_library_import {
    name: "MyImportantAar",
    aars: ["lib/my-important.aar"],
    extract_jni: true,
}

android_app {
    name: "MyAppThatNeedsNativeLibsToo",
    srcs: ["src/**/*.java"],
    optimize: {
        enabled: false,
    },
    certificate: "platform",
    privileged: true,
    static_libs: [
        "MyImportantAar",
    ],
    platform_apis: true,
    use_embedded_native_libs: true,
}

If I make MyAppThatNeedsNativeLibsToo the build succeeds, and I see all the .so files in out/soong/.intermediates/vendor/me/apps/MyAppThatNeedsNativeLibsToo/MyImportantAar/android_common/aar/jni/arm64-v8a. This includes one called libpal_core.so in this case. But if I unzip my APK, I do not see any .so files, and when I run my APK I get:

04-04 19:52:32.286  2850  3073 E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "libpal_core.so" not found
04-04 19:52:32.286  2850  3073 E AndroidRuntime:    at java.lang.Runtime.loadLibrary0(Runtime.java:1077)
04-04 19:52:32.286  2850  3073 E AndroidRuntime:    at java.lang.Runtime.loadLibrary0(Runtime.java:998)
04-04 19:52:32.286  2850  3073 E AndroidRuntime:    at java.lang.System.loadLibrary(System.java:1661)

What have I missed? Do I need to manually unzip the .aar and write a rule for each of the contained .so files? Or is there a way to actually pass the dependencies through using extract_jni?

1 Answer 1

0

The solution is to add product_specific: true, to the android_library_import section of the blueprint file.

I don't know why it works, but I found some instances of cc_prebuilt_library_shared using this flag with the comment:

// Required to 'install' shared objects to /product

So, I gave it a shot, and that alone fixes it. So, my Android.bp import block is simply:

android_library_import {
    name: "MyImportantAar",
    aars: ["lib/my-important.aar"],
    extract_jni: true,
    product_specific: true,
}

And now I see all my .so shared object files in my .apk file if I unzip it with unzip -l MyAppThatNeedsNativeLibsToo.apk

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.