在NDK工程中使用预构建库
=============

在NDK工程中，可以通过CMake语法规则引入并使用预构建库。在引用预构建库时，模块libs目录中的预构建库，以及在CMakeLists.txt编译脚本中声明的预构建库都会被打包。

#### 预构建库使用约束

1.确保引入的SO动态库是通过[HarmonyOS NDK 编译工具链](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/build-with-ndk-overview)编译生成，如何通过[HarmonyOS NDK 编译工具链](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/build-with-ndk-overview)编译预构建库，请参考[CMake构建三方库适配流程](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/toolchain-cmake-build-project#cmake构建三方库适配流程)。

2.确保引入的SO动态库的依赖库也导入到工程中且通过[HarmonyOS NDK 编译工具链](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/build-with-ndk-overview)编译生成。

#### 直接引入预构建库

可以通过直接将预构建的库文件复制到项目文件中, 来使用预构建库。例如在项目中需要使用预构建库libavcodec\_ffmpeg.so，其开发态存放路径如下图所示：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/04/v3/SYk0IM2_ToClFxgVHYzvQg/zh-cn_image_0000002625189041.png?HW-CC-KV=V1&HW-CC-Date=20260612T073806Z&HW-CC-Expire=86400&HW-CC-Sign=6B71022DC51C4386751B5980115147C0ECCBC1E784093CA1221B607C88E73C6D)

在模块的CMakeLists.txt编译脚本中通过add\_library添加所需的预构建库，并声明预构建库路径等信息后，可以在target\_link\_libraries中声明链接该预构建库，脚本示例如下所示：

add\_library(library SHARED hello.cpp)

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)

在模块的CMakeLists.txt编译脚本中添加include\_directories：

include\_directories(
    # ...
    ${CMAKE\_CURRENT\_SOURCE\_DIR}/third\_party/FFmpeg/include
)

当在HAR中使用预构建库时，当前编译的库和链接所需预构建库会打包到HAR中的libs目录下，如下图所示：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e0/v3/HodZL4dbT3GCJ8balLs9xg/zh-cn_image_0000002625109185.png?HW-CC-KV=V1&HW-CC-Date=20260612T073806Z&HW-CC-Expire=86400&HW-CC-Sign=386F5ACC29D9AD6687937A9DD9961013080B00800AE1E247E70B29F916863BBA)

#### \[h2\]预构建库的SONAME问题

请确保引入的预构建动态库（so）正确设置了SONAME。

如果预构建so没有SONAME，链接器将会将so的绝对路径插入到依赖这个so的二进制文件的dynamic section中。当这些二进制文件随hap包发布运行时，动态加载器（dynamic loader）可能最终无法找到这个so而导致错误。

可以使用llvm-readelf工具查看so文件是否设置了SONAME。llvm-readelf工具路径为：${DevEco Studio安装目录}/sdk/default/openharmony/native/llvm/bin或者${command-line-tools安装目录}/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\]

若预构建so使用cmake进行构建，则所有的so默认会设置SONAME（只要目标平台支持）。

若预构建so使用其他构建工具，可以通过配置ldflags来设置。

${...}/clang++ ${...} -Wl,-soname,libavcodec\_ffmpeg.so

#### 使用远程依赖HAR中集成的预构建库

当使用远程依赖HAR中集成的预构建库时，CMakeLists.txt文件中引用脚本如下所示：

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)

#### 使用本地HAR中集成的预构建库

当使用本地HAR中集成的预构建库时，CMakeLists.txt文件中引用脚本如下所示：

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)