Tom Choi
Tom Choi

Reputation: 85

How to use my prebuilt c++ static/shared library in AOSP project

I want use my static or shared prebuilt library libmylib.so or libmylib.a. My build target is Hikey960 device. I success building pure aosp project and flashing to Hikey960 device. Next I want modify /frameworks/av/media/libaudioclient/AudioTrack.cpp using my libmylib.so.

Setp 1

I made mylib directory to /system and copied prebuilt libraries.

|-- Andoird.mk
|-- arm64-v8a
|   |-- shared
|   |   `-- Release
|   |       `-- libmylib.so
|   `-- static
|       `-- Release
|           `-- libmylib.a
|-- armeabi
|   |-- shared
|   |   `-- Release
|   |       `-- libmylib.so
|   `-- static
|       `-- Release
|           `-- libmylib.a
|-- armeabi-v7a
|   |-- shared
|   |   `-- Release
|   |       `-- libmylib.so
|   `-- static
|       `-- Release
|           `-- libmylib.a
|-- include
|   `-- mylib.h
|-- x86
|   |-- shared
|   |   `-- Release
|   |       `-- libmylib.so
|   `-- static
|       `-- Release
|           `-- libmylib.a
`-- x86_64
    |-- shared
    |   `-- Release
    |       `-- libmylib.so
    `-- static
        `-- Release
            `-- libmylib.a

Step 2

I created Android.mk file in /system/mylib as follow

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := system/mylib/$(TARGET_ARCH_ABI)/shared/Release/libmylib.so
LOCAL_EXPORT_C_INCLUDES:= include
include $(PREBUILT_SHARED_LIBRARY)

Step 3

I inserted libmylib line to shared_libs: [ in frameworks/av/media/libaudioclient/Android.bp as follow

cc_library_shared {
    name: "libaudioclient",

    aidl: {
        export_aidl_headers: true,
        local_include_dirs: ["aidl"],
        include_dirs: [
            "frameworks/av/media/libaudioclient/aidl",
        ],
    },

    srcs: [
        // AIDL files for audioclient interfaces
        // The headers for these interfaces will be available to any modules that
        // include libaudioclient, at the path "aidl/package/path/BnFoo.h"
        ":libaudioclient_aidl_private",
        ":libaudioclient_aidl",

        "AudioEffect.cpp",
        "AudioRecord.cpp",
        "AudioSystem.cpp",
        "AudioTrack.cpp",
        "AudioTrackShared.cpp",
        "IAudioFlinger.cpp",
        "IAudioFlingerClient.cpp",
        "IAudioPolicyService.cpp",
        "IAudioPolicyServiceClient.cpp",
        "IAudioTrack.cpp",
        "IEffect.cpp",
        "IEffectClient.cpp",
        "ToneGenerator.cpp",
        "PlayerBase.cpp",
        "RecordingActivityTracker.cpp",
        "TrackPlayerBase.cpp",
    ],
    shared_libs: [
        "libaudiofoundation",
        "libaudioutils",
        "libaudiopolicy",
        "libaudiomanager",
        "libbinder",
        "libcutils",
        "libdl",
        "liblog",
        "libmedia_helper",
        "libmediametrics",
        "libmediautils",
        "libnblog",
        "libprocessgroup",
        "libutils",
        "libvibrator",
        "libmylib",
    ],
    export_shared_lib_headers: ["libbinder"],

    local_include_dirs: ["include/media", "aidl"],
    header_libs: [
        "libaudioclient_headers",
        "libbase_headers",
        "libmedia_headers",
    ],
    export_header_lib_headers: ["libaudioclient_headers"],

    // for memory heap analysis
    static_libs: [
        "libc_malloc_debug_backtrace",
    ],
    cflags: [
        "-Wall",
        "-Werror",
        "-Wno-error=deprecated-declarations",
    ],
    sanitize: {
        misc_undefined : [
            "unsigned-integer-overflow",
            "signed-integer-overflow",
        ],
    },
}

Output

Unfortunatelly, the build failed:

error: frameworks/av/media/libaudioclient/Android.bp:39:1: "libaudioclient" depends on undefined module "libmylib"
06:32:39 soong bootstrap failed with: exit status 1

I think does not include my prebuilt library files when aosp built. how to include my libraries to aosp build. where should I specify mylib?

And I think now use soong as built tool instead of nkd-build in aosp so Should I change my Android.mk file in above I created to Android.bp?

If you know my wrong step, please let me know how to do. thanks.

Upvotes: 7

Views: 7589

Answers (2)

2delta
2delta

Reputation: 101

The bogus998 answer helped me a lot!

One thing that I was struggling with, was that I assumed the 64-bit version of the library suffices, but in our case the build failed because the 32-bit version of the lib was missing. So I created the 32 and 64 bit builds of our library and included it into the system like this:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := [your_library_name]
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_SRC_FILES := arm64-v8a/[your_library_name].so
LOCAL_MULTILIB := 64
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)
LOCAL_MODULE := [your_library_name]
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_SRC_FILES := armeabi-v7a/[your_library_name].so
LOCAL_MULTILIB := 32
include $(BUILD_PREBUILT)

Also in our case the library would be included in the system partition no matter the fact that it was under vendor/external/[your_library_name], and adding the LOCAL_VENDOR_MODULE := true fixed that.

Upvotes: 2

bogus998
bogus998

Reputation: 136

Regarding Android.mk vs Android.bp file, probably it will be good choice to learn Soong since Google is slowly converting make files to new build system.

Here are good place to start if you would like to start using Soong:


About adding custom library. Since project treble customization of Android should be done in vendor image. You will have less problems if you would like to update Android framework in future. https://android-developers.googleblog.com/2017/05/here-comes-treble-modular-base-for.html

In order to add custom library to vendor you need to do several things. With these steps I managed to add successfully pre-built shared (.so) library. Still don't know how to add pre-build static (.a) library to system.

  1. In order to add library to vendor partition, you need to create text file which lists all added libraries. Since Android N (7.0) or later, apps are only allowed to access libraries on a specific whitelist of NDK libraries.

    Sample files :

    • system/core/rootdir/etc/public.libraries.android.txt for main Android
    • system/core/rootdir/etc/public.libraries.wear.txt for Android Wear devices
    • system/core/rootdir/etc/public.libraries.iot.txt for Android Things devices

We can create counterpart file for vendor and create it in following path: /vendor/etc/public.libraries.txt

  1. Next since Android 8.0 (Oreo) the native library in vendor must be properly labeled so it can be accessible to apps. We need to update SELinux file and add proper context for resource file, our library.

    • Create directory vendor/[your_vendor]/sepolicy and add "file_contexts" file

    • Add label for our file resource in the "file_contexts" -> vendor/lib(64)?/[your_lib_name]\.so u:object_r:same_process_hal_file:s0.

    File context label follows form of user:role:type:sensitivity. If access is required by any apps (including third party apps), the library must be labeled as same_process_hal_file. This rule is defined in system/sepolicy/public/file.te

    • Remember to add new line after entry. Otherwise first line of next "file_contexts" file will be concatenated during build and you will get error.

    After build you can check if your "file_contexts" was added properly. Output of all file_contexts files is in: out/target/product/generic_x86_64/obj/ETC/file_contexts.bin_intermediates/file_contexts.device.tmp. All entries are preceded with comment and path to file_contexts. In our case you should find in file comment "vendor/[your_vendor]/sepolicy/file_contexts".

  2. In [your_vendor] directory you should have your product.mk file. You can find examples of this files in /device. Update your product.mk file and add BOARD_VENDOR_SEPOLICY_DIRS. →

    BOARD_VENDOR_SEPOLICY_DIRS += \ vendor/[your_vendor]/sepolicy \

    In SELinux documentation it is stated that Vendor sepolicy are located under BOARD_SEPOLICY_DIRS paths, but in system/sepolicy/Android.mk we can read that this field is deprecated :

    "BOARD_SEPOLICY_DIRS was used for vendor/odm sepolicy customization before. It has been replaced by BOARD_VENDOR_SEPOLICY_DIRS (mandatory) ..."

  3. Add library as a product package in your product.mk file.

PRODUCT_PACKAGES += \ {your_library_name} \

  1. Build and test

Now your library should be visible in AOSP.

If you would like to use this library in vendor image, you need to specify it in library .mk /. bp file according to VNDK.

Check out this link for more info:

Upvotes: 7

Related Questions