鸿蒙 NDK开发:使用预构建库(四)
·

在NDK工程中,可以通过CMake语法规则引入并使用预构建库。模块libs目录中的预构建库,以及在CMakeLists.txt中声明的预构建库都会被打包。
一、预构建库使用
| 约束 | 说明 |
|---|---|
| 编译工具链 | 确保引入的SO动态库是通过HarmonyOS NDK编译工具链生成的 |
| 依赖库 | 确保引入的SO动态库的依赖库也导入到工程中,且通过HarmonyOS NDK编译工具链生成 |
二、直接引入预构建库
2.1 文件结构示例
预构建库文件存放路径示例:
entry/src/main/
├── cpp/
│ ├── third_party/
│ │ └── FFmpeg/
│ │ ├── include/ # 头文件目录
│ │ └── libs/ # 库文件目录
│ │ ├── arm64-v8a/
│ │ │ └── libavcodec_ffmpeg.so
│ │ └── armeabi-v7a/
│ │ └── libavcodec_ffmpeg.so
│ └── CMakeLists.txt
2.2 CMakeLists.txt配置
# 添加源码产物
add_library(library SHARED hello.cpp)
# 添加预构建库(IMPORTED表示预构建)
add_library(avcodec_ffmpeg SHARED IMPORTED)
# 设置预构建库的属性
set_target_properties(avcodec_ffmpeg
PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/third_party/FFmpeg/libs/${OHOS_ARCH}/libavcodec_ffmpeg.so
)
# 声明链接该预构建库
target_link_libraries(library PUBLIC libace_napi.z.so avcodec_ffmpeg)
# 添加头文件目录
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/third_party/FFmpeg/include
)
说明:
-
add_library(avcodec_ffmpeg SHARED IMPORTED):IMPORTED表示这是预构建库,不需要编译 -
set_target_properties:设置IMPORTED_LOCATION属性指定库文件路径 -
${OHOS_ARCH}:根据编译架构自动选择对应目录(arm64-v8a/armeabi-v7a等)
2.3 HAR中使用预构建库
当在HAR中使用预构建库时,当前编译的库和链接所需预构建库会打包到HAR中的libs目录下。
三、预构建库的SONAME问题
如果预构建SO没有设置SONAME,链接器将会将SO的绝对路径插入到依赖这个SO的二进制文件的dynamic section中。当这些二进制文件随HAP包发布运行时,动态加载器可能最终无法找到这个SO而导致错误。
检查SONAME
使用llvm-readelf工具查看SO文件是否设置了SONAME:
# 工具路径
${DevEco Studio安装目录}/sdk/default/openharmony/native/llvm/bin/llvm-readelf
# 示例命令
${YOUR_PATH}/command-line-tools/sdk/default/openharmony/native/llvm/bin/llvm-readelf -d libavcodec_ffmpeg.so | grep SONAME
# 正确输出示例
0x000000000000000e (SONAME) Library soname: [libavcodec_ffmpeg.so]
设置SONAME的方法
| 构建方式 | 设置方法 |
|---|---|
| CMake构建 | 默认会设置SONAME(只要目标平台支持) |
| 其他构建工具 | 通过配置ldflags设置:clang++ ... -Wl,-soname,libavcodec_ffmpeg.so |
四、使用远程依赖HAR中集成的预构建库
# 设置依赖路径
set(DEPENDENCY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules)
# 添加预构建库
add_library(library SHARED IMPORTED)
# 设置库文件路径
set_target_properties(library
PROPERTIES
IMPORTED_LOCATION ${DEPENDENCY_PATH}/library/libs/${OHOS_ARCH}/liblibrary.so
)
# 链接到主产物
add_library(entry SHARED hello.cpp)
target_link_libraries(entry PUBLIC libace_napi.z.so library)
路径说明:../../../oh_modules是远程依赖HAR在工程中的默认存放位置。
五、使用本地HAR中集成的预构建库
# 设置本地HAR库路径
set(LIBRARY_DIR "${NATIVERENDER_ROOT_PATH}/../../../../library/build/default/intermediates/libs/default/${OHOS_ARCH}/")
# 添加预构建库
add_library(library SHARED IMPORTED)
# 设置库文件路径
set_target_properties(library
PROPERTIES
IMPORTED_LOCATION ${LIBRARY_DIR}/liblibrary.so
)
# 链接到主产物
add_library(entry SHARED hello.cpp)
target_link_libraries(entry PUBLIC libace_napi.z.so library)
六、核心点
| 要点 | 说明 |
|---|---|
| 预构建库声明 | add_library(库名 SHARED IMPORTED) |
| 路径设置 | set_target_properties + IMPORTED_LOCATION |
| 架构区分 | 使用${OHOS_ARCH}变量区分不同架构 |
| SONAME要求 | 预构建SO必须设置SONAME,否则运行时可能加载失败 |
| 打包范围 | libs目录中的预构建库和CMakeLists.txt中声明的都会被打包 |
路径类型
| 路径类型 | 说明 | 示例 |
|---|---|---|
| 本地预构建库 | 工程内直接引用 | ${CMAKE_CURRENT_SOURCE_DIR}/libs/${OHOS_ARCH}/xxx.so |
| 远程HAR依赖 | 通过ohpm依赖的HAR | ${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules/xxx/libs/${OHOS_ARCH}/xxx.so |
| 本地HAR依赖 | 本地HAR的构建产物 | ${NATIVERENDER_ROOT_PATH}/../../../../library/build/default/intermediates/libs/default/${OHOS_ARCH}/ |
更多推荐



所有评论(0)