解决 CMake 编译时 “undefined reference“ 问题:RPATH 与 rpath-link

在使用 CMake 编译基于第三方动态库 的项目时,你是否遇到过类似下面的报错?

/home/user/toolchain/bin/ld: CMakeFiles/test.dir/example/demo.cpp.o: in function `xxxxxxx':
demo.cpp:(.text+0x588): undefined reference to `xxxxxxxxx'
/home/user/toolchain/bin/ld: demo.cpp:(.text+0x60c): undefined reference to `RK_MPI_SYS_Init'
...

错误原因

  • 这些 undefined reference 错误表明 链接器在编译时找不到动态库。

  • 但动态库明明在 ../lib/ 目录下,为什么找不到?

  • 可能的原因是 RPATH(运行时库路径)设置不正确,导致链接器和运行时都找不到这些库。

解决方案:使用 set_target_properties

CMakeLists.txt 中添加以下代码,确保 CMake 在编译和运行时都能正确找到 ../lib/ 目录下的动态库:

set_target_properties(test PROPERTIES
    INSTALL_RPATH "../lib"  # 设置 RPATH,运行时会优先从 "../lib" 目录查找动态库
    CMAKE_BUILD_WITH_INSTALL_RPATH TRUE  # 让 CMake 在编译时就使用 INSTALL_RPATH
    LINK_FLAGS "-Wl,-rpath-link,../lib,../lib/xxxx.so"  # 告诉链接器去 "../lib" 目录查找动态库
)

解释:

  • INSTALL_RPATH "../lib"

    • 设置 test 运行时的 RPATH,让它自动从 ../lib 目录查找xxxxx.soxxxx.so,避免 ldd 查找失败。

  • CMAKE_BUILD_WITH_INSTALL_RPATH TRUE

    • 让 CMake 在编译时就使用 INSTALL_RPATH,避免找不到共享库的问题。

  • -Wl,-rpath-link,../lib,../lib/xxxxx.so

    • -Wl 让 CMake 直接传递参数给链接器 ld

    • -rpath-link,../libld 在编译时就能找到 xxxxx.so

    • ../lib/libeasymedia.so 确保 ld 也能解析 libeasymedia.so 的依赖

如何检查是否生效?

1️⃣ 检查 librk_mpi.so 是否在 ../lib/ 目录下

ls -l ../lib/

2️⃣ 检查 dms_test 是否正确链接动态库

ldd test

 如果输出中动态库都正确解析,说明 RPATH 设置正确。

3️⃣ 确保 CMake 生成的 test 包含 rpath

readelf -d test | grep RPATH

如果输出包含 ../lib,说明 RPATH 设置成功

总结

如果你的 CMake 编译时报 undefined reference,并且你确定动态库存在,那么很可能是 RPATH 配置问题。

解决方案

  1. 使用 INSTALL_RPATH 让程序运行时正确找到动态库。

  2. 使用 -Wl,-rpath-link 让链接器在编译时找到动态库。

  3. 检查 ls -l ../lib/ldd testreadelf -d test 确保路径正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值