C/C++ link-undefined 问题总结

博客探讨了Linux系统中动态库和静态库的链接问题,包括未链接库、库顺序错误、错误库引用等常见问题,并提供了-Wl,--start-group和--end-group的解决策略。还详细介绍了动态库和静态库的搜索路径,以及如何使用ldd和objdump检查依赖。此外,提到了GDB查看内存块内容的方法,以及在CMake中遇到的问题和解决办法,如CPMFindPackage未找到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可能问题

1. 没有链接对应的库;

2. 如果是静态库可能是库的链接顺序的问题;可以通过-Wl,--start-group -Wl,--end-group来排查;

3. 链接到错误的库,其他库中存在同名但是定义不同的函数,此时找到对应的错误链接的库,并将其改到合适的位置,或者删除;

4. -D_GLIBCXX_USE_CXX11_ABI=1,What is the "C++ ABI Specification" referred to in GCC's manual? - Stack Overflow 这种情况下还是3的问题,还是的签名没有对应。

ld 杂记

搜索顺序

动态链接库的搜索顺序

   1. 编译目标代码时指定的动态库搜索路径

   2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径

   3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径

   4. 默认的动态库搜索路径/lib 

   5. 默认的动态库搜索路径/usr/lib 


静态链接库的搜索顺序

   1. ld会去找GCC命令中的参数-L

   2. 再找gcc的环境变量LIBRARY_PATH

   3. 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的 
 

查看ld的搜索路径:

/usr/bin/ld --verbose | grep SEARCH

cmake 显示g++ command过程

set(CMAKE_VERBOSE_MAKEFILE on)

cmake 显示ld command过程

target_link_libraries(name INTERFACE -Wl,-v lib-name)

查看依赖

查看执行文件的依赖:

ldd exec-file

产看so的依赖:

objdump -x *.so | grep NEEDED

CMake-CPM的使用

CMake Error at /disk4/xinrong.ypc/onnxruntime/build/Linux/Debug/_deps/rapids-cmake-src/rapids-cmake/cpm/find.cmake:152 (CPMFindPackage):
  Unknown CMake command "CPMFindPackage".
Call Stack (most recent call first):
  /disk4/xinrong.ypc/onnxruntime/build/Linux/Debug/_deps/rapids-cmake-src/rapids-cmake/cpm/thrust.cmake:72 (rapids_cpm_find)
  external/cuCollections/cmake/thirdparty/get_thrust.cmake:18 (rapids_cpm_thrust)
  external/cuCollections/cmake/thirdparty/get_thrust.cmake:22 (find_and_configure_thrust)
  external/cuCollections/CMakeLists.txt:62 (include)

 原因可能是:CPM对应的cmake文件(里面包含了CPMFindPackage的实现)没有下载成功。

GDB 查看连续内存块内容

格式

x /nfu

参数说明

  • x是 examine 的缩写
  • n表示要显示的内存单元的个数
  • f表示显示方式, 可取如下值

                x 按十六进制格式显示变量
                d 按十进制格式显示变量
                u 按十进制格式显示无符号整型
                o 按八进制格式显示变量
                t 按二进制格式显示变量
                a 按十六进制格式显示变量
                i 指令地址格式
                c 按字符格式显示变量
                f 按浮点数格式显示变量

  • u表示一个地址单元的长度

                b表示单字节
                h表示双字节
                w表示四字节
                g表示八字节

看到vector变量:

链接问题

动态库链接静态库时

报relocation的错误,原因在于动态库链接静态库libprotobuf.a时,使用了-fPIC,但是编译libprotobuf.a时没有用-fPIC,导致libprotobuf.a的代码定向失败。PIC,全称是Position Independent Code,加了后,生成的库的起始地址就不再是0,而是相对地址,加载时会进行两次跳转,并由dynamic-loader(ld-linux.so)填充最终跳转地址。

解决方案

        编译libprotobuf.a时,也加上-fPIC。

        注意:-fPIC对静态库和动态库都可以加。主要是对跳转的地址编码方式不同。

参考

linux中的ld命令及其搜索路径顺序_Cc1924的博客-CSDN博客_ld命令

学习笔记:relocation R_X86_64_32 against `.rodata‘ can not be used when making a shared object;_fanchenxinok的博客-CSDN博客 gcc 编译参数 -fPIC 作用_Ruo_Xiao的博客-CSDN博客_fpic
GCC -fPIC 选项生成位置无关代码(Position-Independent Code) – 悠然品鉴-

g++ -std=c++11 -I/usr/include -I/usr/local/include -I/home/tian/opencv-4.1.0/include -I/home/tian/opencv-4.1.0/build -I/home/tian/opencv-4.1.0/modules/core/include -I/home/tian/opencv-4.1.0/modules/calib3d/include -I/home/tian/opencv-4.1.0/modules/features2d/include -I/home/tian/opencv-4.1.0/modules/flann/include -I/home/tian/opencv-4.1.0/modules/dnn/include -I/home/tian/opencv-4.1.0/modules/objdetect/include -I/home/tian/opencv-4.1.0/modules/stitching/include -I/home/tian/opencv-4.1.0/modules/ml/include -I/home/tian/opencv-4.1.0/modules/imgproc/include -I/home/tian/opencv-4.1.0/modules/photo/include -I/home/tian/opencv-4.1.0/modules/video/include -I/home/tian/opencv-4.1.0/modules/videoio/include -I/home/tian/opencv-4.1.0/modules/imgcodecs/include -I/home/tian/opencv-4.1.0/modules/highgui/include -I/home/tian/ofcs/src/SeetaFace6OpenBinary-main/CPU/SeetaFace/index/build/include -o test test.o -L/usr/local/lib -L/usr/lib64 -L/home/tian/ofcs/src/SeetaFace6OpenBinary-main/CPU/SeetaFace/index/build/lib64 -lSeetaFaceDetector600 -lSeetaFaceLandmarker600 -lSeetaFaceRecognizer610 -lopencv_world -lm test.o: In function `test1()': test.cpp:(.text+0x76f): undefined reference to `cv::imread(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)' test.cpp:(.text+0xa3d): undefined reference to `cv::imshow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::_InputArray const&)' test.cpp:(.text+0xaf7): undefined reference to `cv::imread(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)' test.cpp:(.text+0xd85): undefined reference to `cv::imshow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::_InputArray const&)' collect2: error: ld returned 1 exit status make: *** [Makefile:33: test] Error 1
最新发布
03-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值