如何在AOSP项目中使用我预先构建的c++静态/共享库



我想使用我的静态或共享预构建库libmylib.so or libmylib.a。我的构建目标是Hikey960设备。我成功地构建了纯aosp项目并向Hikey960设备闪烁。接下来,我想使用我的libmylib.so修改/frameworks/av/media/libaudioclient/AudioTrack.cpp

设置1

我将mylib目录制作为/system,并复制了预构建的库。

|-- 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

步骤2

我在/system/mylib中创建了Android.mk文件,如下所示

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)

步骤3

我将libmylib行插入frameworks/av/media/libaudioclient/Android.bp中的shared_libs: [,如下所示

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",
],
},
}

输出

不幸的是,构建失败了:

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

我认为在aosp构建时不包括我的预构建库文件。如何将我的库包含到aosp构建中。我应该在哪里指定mylib?

我认为现在在aosp中使用soong作为构建工具,而不是nkd构建,所以我应该把上面我创建的Android.mk文件改为Android.bp吗?

如果你知道我的错误步骤,请告诉我该怎么做。谢谢。

关于Android.mk与Android.bp文件,学习宋可能是个不错的选择,因为谷歌正在慢慢地将make文件转换为新的构建系统。

如果你想开始使用宋:,这里是一个很好的起点

  • https://android.googlesource.com/platform/build/soong/+/master/README.md
  • https://ci.android.com/builds/submitted/6350183/linux/latest/view/soong_build.html

关于添加自定义库。由于项目三重定制的Android应该在供应商的形象。如果你想在未来更新安卓框架,你会有更少的问题。https://android-developers.googleblog.com/2017/05/here-comes-treble-modular-base-for.html

为了向供应商添加自定义库,您需要做几件事。通过这些步骤,我成功地添加了预构建的共享(.so)库。仍然不知道如何将预构建的静态(.a)库添加到系统中。

  1. 为了将库添加到供应商分区,您需要创建列出所有添加库的文本文件。自Android N(7.0)或更高版本以来,应用程序只允许访问NDK库的特定白名单上的库。

    示例文件:

    • system/core/rootdir/etc/public.libraries.android.txt适用于主要Android
    • 适用于Android Wear设备的system/core/rootdir/etc/public.libraries.wear.txt
    • 适用于Android Things设备的system/core/rootdir/etc/public.libraries.iot.txt

我们可以为供应商创建对应文件,并在以下路径中创建:/vendor/etc/public.libraries.txt

  1. 下一步,由于Android 8.0(奥利奥),供应商中的本地库必须正确标记,以便应用程序可以访问。我们需要更新SELinux文件,并为我们的库资源文件添加适当的上下文。

    • 创建目录vendor/[your_vendor]/sepolicy并添加"file_contexts"文件

    • 在"file_contexts"->vendor/lib(64)?/[your_lib_name].so u:object_r:same_process_hal_file:s0中为我们的文件资源添加标签。

    文件上下文标签遵循user:role:type:sensitivity的形式。如果任何应用程序(包括第三方应用程序)都需要访问,则库必须标记为same_process_hal_file。此规则在system/sepolicy/public/file.te中定义

    • 记住在输入后添加新行。否则,在构建过程中,下一个"file_contexts"文件的第一行将被连接起来,您将得到错误

    构建后,您可以检查是否正确添加了"file_contexts"。所有file_context文件的输出格式为:out/target/product/generic_x86_64/obj/ETC/file_contexts.bin_intermediates/file_contexts.device.tmp。所有条目前面都有注释和file_contexts的路径。在我们的案例中,您应该在文件注释"vendor/[your_vendor]/sepolicy/file_contexts"中找到。

  2. 在[your_vendor]目录中,应该有product.mk文件。您可以在/device中找到这些文件的示例。更新product.mk文件并添加BOARD_VENDOR_SEPOLICY_DIRS。→

    BOARD_VENDOR_SEPOLICY_DIRS += vendor/[your_vendor]/sepolicy

    在SELinux文档中,供应商sepolicy位于BOARD_sepolicy_DIRS路径下,但在system/sepolicy/Android.mk中,我们可以看到该字段已被弃用:

    "BOARD_SELPOLICY_DIRS以前用于供应商/odm策略自定义。它已被BOARD_vendor_SEPOLICY_DIRS(必需)取代…">

  3. 将库作为产品包添加到product.mk文件中。

PRODUCT_PACKAGES += {your_library_name}

  1. 构建和测试

现在您的库应该在AOSP中可见。

如果您想在供应商映像中使用此库,则需要在library.mk/中指定它。根据VNDK的bp文件。

查看此链接了解更多信息:

  • https://source.android.com/devices/architecture/vndk/build-system
  • https://source.android.com/devices/tech/config/namespaces_libraries#adding-其他本机库
  • https://source.android.com/security/selinux/build#android-o-build

bogus998的答案对我帮助很大!

我一直在努力解决的一件事是,我认为64位版本的库就足够了,但在我们的案例中,由于缺少32位版本的lib,构建失败了。因此,我创建了我们库的32位和64位构建,并将其包含在系统中,如下所示:

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)

同样在我们的情况下,无论库在vendor/external/[your_library_name]下,它都将被包括在system分区中,并且添加LOCAL_VENDOR_MODULE:=true修复了这一问题。

最新更新