Cattivo
Cattivo

Reputation: 752

Error adding prebuilt apk with shared libraries to AOSP

I tried to add a prebuilt APK to my Android build. The APK contains several shared libraries (*.so files). It compiles without problem, but I still get an error from the app indicating that the libraries cannot be found.

Why could this be?

Here is the android.mk code:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := apkwithso
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_REQUIRED_MODULES := libx liby libz
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)

libx, y, z are my libx.so, liby.so, and libz.so

I also tried to copy the .so manually from the APK to the out lib directories but it didn't work.

I am compiling with Android 4.1.2 for Galaxy Nexus Maguro.

Upvotes: 11

Views: 17570

Answers (6)

olin00
olin00

Reputation: 1

The apk needs to be zipaligned with parameter '4' for this specific purpose. If an external apk is used, then zipalign must be done manually or else the .so file inside the apk will refuse to load because of the wrong alignment. Even though you might think that the gradle build of your app already did a zipalign, that zipalign might not be aligned to the offsets required. If zipalign does not solve the issue, then check Android source code: bionic/linker/linker.cpp, function open_library_in_zipfile() which might give you more clues why the library is not loaded.

Upvotes: 0

Benny
Benny

Reputation: 2331

My Instructions is not about your error! But it may be helpful for similar error

If you try to copy prebuilt apk using:

PRODUCT_COPY_FILES += $(LOCAL_PATH)/prebuilt/filename.apk

and you getting this error:

Prebuilt apk found in PRODUCT_COPY_FILES: ... , use BUILD_PREBUILT instead!. Stop.

You can remove this check my modify the file build/core/MakeFile and comment this lines:

define check-product-copy-files
$(if $(filter %.apk, $(call word-colon, 2, $(1))),$(error \
    Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!))
endef

by inserting # before each line

Upvotes: 3

Justin Buser
Justin Buser

Reputation: 2871

Files can also be be specified in aospSource:destinationOnImage format like this in the device-partial.mk when adding a custom vendor directory:

PRODUCT_COPY_FILES += \
    vendor/your-custom-vendor/your-device/proprietary/libx.so:system/lib/libx.so

You can add pretty much anything you like here (other than .apk files), and it will be copied to your image.

Upvotes: 1

Michael
Michael

Reputation: 1503

Too add multiple libraries to one apk one additional section (as in answer of Justin Buser) should be added for each separate library.

Upvotes: 0

Justin Buser
Justin Buser

Reputation: 2871

I've had this problem myself, the reason is that when APK files are included in a build they are essentially bypassing the installation process. This installation process is the point at which any shared libraries are extracted from the apk and put in the appropriate place, ergo if that never happens the libraries will not be available. This is because packages that are built from source during the AOSP build either have their prebuilt shared libraries included during that build process or their libraries are also built from source, and in either case those libraries are put in the appropriate place.

For this reason in addition to the apk module itself you should add the following in the same .mk file:

include $(CLEAR_VARS)
LOCAL_MODULE := libapkwithso
LOCAL_SRC_FILES := lib/libapkwithso.so # or wherever your so is
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
include $(BUILD_PREBUILT)

Then add:

LOCAL_REQUIRED_MODULES := libapkwithso

Upvotes: 18

Yury
Yury

Reputation: 20936

BUILD_PREBUILT calls prebuild.mk script. The description of this script is the following:

Standard rules for copying files that are prebuilt

It does not tell that the application will be installed. So I think that is why your application cannot find the libraries.

The solution is to extract libraries from the package and copy them separately from the application. The details how to do this you can find here.

Upvotes: 8

Related Questions