Android15 Camera HAL Android.bp中引用Android.mk编译的libB.so

背景描述

Android15 Camera HAL使用Android.bp脚本来构建系统。假设Camera HAL中引用了另外一个HAL实现的so (例如VPU HAL), 恰巧被引用的这个VPU HAL so是用Android.mk构建的,那Camera HAL Android.bp在直接引用这个Android.mk编译出来的so时很可能会出现链接问题。

那么这时候有啥曲线救国方法能让Camera HAL Android.bp成功引用这个VPU HAL so吗?

先说第一个方案:

  1. VPU HAL so改Android.mk编译为Android.bp,然后生成lib/libvpu_pv.so和lib64/libvpu_pv.so。
  2. Camera HAL路径下建一个目录放要引用的so和头文件。
  3. Camera HAL Android.bp中添加vpu so的预编译目标。
  4. Camera HAL Android.bp中添加对vpu引用。

注意:VPU HAL Android.mk和Android.bp编译出来的so符号要避免冲突。

VPU HAL Android.bp构建so

XML 复制代码
cc_library_shared {
    name: "libarm_vpu_jpegenc_wr",
    vendor: true,
    srcs: [
        vpu_wrapper/encoder/jpeg_encoder_wrap/arm_jpeg_encoder.c",
    ],

    include_dirs: [
        "vendor/qc/hardware/modules/vpu/libs/inc",
        "vendor/qc/hardware/modules/vpu/wrapper/encoder/jpeg_enc",
    ],

    static_libs: [
        "libh2enc",
    ],

    header_libs: [
        "libhardware_headers",
        "arm_gralloc_headers",
    ],

    shared_libs: [
        "libcutils",
        "libc",
        "liblog",
        "libcutils",
    ],

    defaults: [
        "memory_allocator_defaults",
    ],

    export_include_dirs: [
        "vendor/qc/hardware/modules/vpu/wrapper/encoder/jpeg_enc",
    ],
}

这里将生成vendor/lib/libarm_vpu_jpegenc_wr.so和vendor/lib64/libarm_vpu_jpegenc_wr.so。

vpu so放到Camera HAL

这里如下放置:vendor/qc/hardware/modules/camera/devices/EmulatedCamera/hwl/ext_lib/lib/libarm_vpu_jpegenc_wr.so

vendor/qc/hardware/modules/camera/devices/EmulatedCamera/hwl/ext_lib/lib64/libarm_vpu_jpegenc_wr.so

vendor/qc/hardware/modules/camera/devices/EmulatedCamera/hwl/ext_inc/arm_vpu_jpegenc_wr.h

Camera HAL添加vpu预编译目标

XML 复制代码
cc_prebuilt_library_shared {
    name "libarm_vpu_jpegenc_wr",
    vendor: true,
    strip: { none: true },
    compile_multilib: "both",

    arch: {
        arm: {
            srcs: ["ext_lib/lib/libarm_vpu_jpegenc_wr.so"],
            relative_install_path: ".",
        },
        arm64: {
            srcs: ["ext_lib/lib64/libarm_vpu_jpegenc_wr.so"],
            relative_install_path: ".",
        },
    },

    shared_libs: [
        "libutils",
        "liblog",
        "libcutils",
        "libdmabufheap",
    ],
}

Camera HAL中添加对vpu的引用

XML 复制代码
//主要是两个内容:头文件路径和so应用
...
xx {
    ...
    shared_libs: [
        ...
        "libarm_vpu_jpegenc_wr",
    ],

    include_dirs: [
        ...
        "vendor/qc/hardware/modules/camera/devices/EmulatedCamera/hwl/ext_inc",
    ],
    ...
}

可能遇到的问题

out/soong/.intermediates/vendor/qc/hardware/modules/camera/devices/EmulatedCamera/hwl/libarm_vpu_jpegenc_wr/android_vendor.35_arm64_armv8-a_shared/libarm_vpu_jpegenc_wr.so: error: DT_NEEDED "libutils.so" is not specified in shared_libs.

问题原因

  • DT_NEEDED

    是 ELF 文件(共享库)中的一个字段,用于指定该库依赖的其他共享库。加载器会根据 DT_NEEDED 动态加载依赖库。

  • 库文件 libarm_vpu_jpegenc_wr.so 依赖 libutils.so,但在 Android.bpshared_libs 中未声明该依赖。

解决方法

在Android.bp中添加缺失的依赖,对于这里的例子,就是:

out/soong/.intermediates/vendor/qc/hardware/modules/camera/devices/EmulatedCamera/hwl/libarm_vpu_jpegenc_wr/android_vendor.35_arm_armv8-a_shared/libarm_vpu_jpegenc_wr.so: error: DT_SONAME "libarm_vpu_jpegenc.so" must be equal to the file name "libarm_vpu_jpegenc_wr.so".

问题的原因

  • DT_SONAME

    是 ELF 文件(共享库)中的一个字段,用于指定动态链接时的库名称。加载器会根据 DT_SONAME 查找库文件。

  • 库文件 libarm_vpu_jpegenc_wr.soDT_SONAME 被设置为 libarm_vpu_jpegenc.so,而 Android 构建系统要求 DT_SONAME 必须与库文件名一致。

Camera HAL Android.bp中cc_prebuilt_library_shared libarm_vpu_jpegenc_wr, 构建的src虽然是libarm_vpu_jpegenc_wr.so, 单这个so构建脚本(VPU HAL Android.bp)中cc_library_shared 是arm_vpu_jpegenc。 即DT_SONAME需要和库文件名不一致。

解决方法

修改VPU HAL Android.bp cc_library_shared目标名为libarm_vpu_jpegenc_wr。