CMake依赖第三方so库


本文以在Android App工程中依赖xhook为例,记录如何在CMakeLists.txt中依赖外部第三方so库。


编译xhook


1 下载xhook源码

git clone https://github.com/iqiyi/xHook.git


2 修改支持的abi

cd xHook

xHook 支持armeabi, 需要使用android-ndk 16, 因为android-ndk 17以上已经不支持armeabi了。如果不需要armeabi,并且使用高版本的android-ndk,可以去掉xHook对armeabi的支持。

打开 ./libxhook/jni/Application.mk删除armeabi:

在这里插入图片描述

3 编译xhook

执行以下命令,编译xHook:

./build_libs.sh

该脚本会调用ndk-build命令,需要先将ndk的目录配置在~/.bashrc中:

export PATH=/home/zhangjg/tools/android-ndk-r21:$PATH

./build_libs.sh 执行完成之后,会输出armeabi-v7a, arm64-v8a,x86,x86_64的so:

在这里插入图片描述


将xhook加到项目中


1 将libxhook/libs目录拷贝到项目中

拷贝到CMakeLists.txt文件所在的目录, 一般为app/src/main/cpp中:

在这里插入图片描述

2 将xhook.h拷贝到项目中

为了方便配置,直接将xhook.h拷贝到app/src/main/cpp中,和CMakeLists.txt在同级目录:

在这里插入图片描述

3 依赖xhook.h写hook的逻辑

#include "xhook.h"

static void fake_abort() {
    LOGI("fake abort");
}

static void do_hook() {
    xhook_register("ibchrome.so", "abort", (void *)fake_abort, nullptr);
    xhook_refresh(0);
}

编译以上代码,发现链接错误:

[2/2] Linking CXX shared library /home/zhangjg/AndroidStudioProjects/BLEDemo/app/build/intermediates/cmake/debug/obj/arm64-v8a/libble_compat.so
FAILED: /home/zhangjg/AndroidStudioProjects/BLEDemo/app/build/intermediates/cmake/debug/obj/arm64-v8a/libble_compat.so 
: && /home/zhangjg/tools/android-ndk-r21/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=aarch64-none-linux-android26 --gcc-toolchain=/home/zhangjg/tools/android-ndk-r21/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/zhangjg/tools/android-ndk-r21/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security   -std=c++11 -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libble_compat.so -o /home/zhangjg/AndroidStudioProjects/BLEDemo/app/build/intermediates/cmake/debug/obj/arm64-v8a/libble_compat.so CMakeFiles/ble_compat.dir/ble_compat.cpp.o  /home/zhangjg/tools/android-ndk-r21/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/26/liblog.so /home/zhangjg/.gradle/caches/transforms-2/files-2.1/bba815dfd2e33446c27bb2585a849af4/jetified-xdl-1.0.4/prefab/modules/xdl/libs/android.arm64-v8a/libxdl.so -latomic -lm && :
CMakeFiles/ble_compat.dir/ble_compat.cpp.o: In function `do_hook()':
/home/zhangjg/AndroidStudioProjects/BLEDemo/app/src/main/cpp/ble_compat.cpp:133: undefined reference to `xhook_register'
/home/zhangjg/AndroidStudioProjects/BLEDemo/app/src/main/cpp/ble_compat.cpp:134: undefined reference to `xhook_refresh'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

我们都知道,c/c++代码的构建分为编译和链接两个部分,编译期间依赖的头文件xhook.h是没有问题的。但是链接的时候,即使我们自己的so是动态链接到libxhook.so,连接器ld也是要找到libxhook.so,去检查libxhook.so中的符号,以确保我们自己的so中的符号,需要做静态链接还是动态链接。

以上错误就是因为链接器不知道去哪里找libxhook.so。

需要在CMakeLists.txt中加入相关的配置:

add_library(xhook SHARED IMPORTED)
set_target_properties(xhook PROPERTIES IMPORTED_LOCATION
        ${PROJECT_SOURCE_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}/libxhook.so)

target_link_libraries(ble_compat xhook)

add_library(xhook SHARED IMPORTED)

这句话的意思是,定义一个库,这个库需要有一个名字xhook,这个名字可以被其他库依赖。


set_target_properties

这句话是对xhook这个库进行配置,主要是配置它的so的路径。${PROJECT_SOURCE_DIR}就是当前CMakeLists.txt文件所在的路径app/src/main/cpp${CMAKE_ANDROID_ARCH_ABI}就是当前编译任务对应的abi(armeabi-v7a, arm64-v8a, x86, x86_64)。

上面的两句代码定义了xhook这个库,并且指定了这个库的so的位置。


target_link_libraries(ble_compat xhook)

这句话说明当前的模块ble_compat需要链接到xhook这个库。


加上上面的代码后,就可以编译通过了。

并且在打包apk的时候,会自动把libxhook.so打进去。


我之前不会配置如何链接外部第三方so,就在网上搜了很多资料,很多都是使用link_directories()配置的,都不生效。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CMake中安装第三方有多种方法。一种常见的方法是使用find_package命令。这个命令可以用来查找和引入系统已经安装的。您可以在CMakeLists.txt文件中使用find_package命令,并指定您要引入的的名称。CMake会根据您的系统配置自动查找这个,并将其引入到您的项目中。这种方法的优点是简单方便,不需要手动下载和设置的构建过程。 另一种方法是使用include(FetchContent)命令。这个命令允许您从指定的URL或Git存储中提取第三方,并将其作为CMake项目的子目录构建。使用FetchContent命令时,您无需手动下载、解压缩或设置外部的构建过程,CMake会自动执行这些任务。这种方法的优点是它使得引入第三方更加方便,并且使得与外部的集成更加简单。同时,使用FetchContent命令时,您可以很容易地在您的CMake项目中指定外部的版本和源代码位置。 另外,对于Android开发,您可以使用NDK-Build编译出各平台的so文件,然后将这些文件引入到您的CMake项目中。这种方法适用于调用第三方的场景。您可以在CMakeLists.txt文件中使用add_library命令,将这些so文件添加到您的项目中。 综上所述,安装第三方的方法包括使用find_package命令、include(FetchContent)命令和使用NDK-Build编译出so文件。您可以根据您的具体需求和项目情况选择适合的方法来安装第三方。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值