文章目录
- 1.linux下查找库文件所在位置
- 2.如何查看库里面包含的函数
- 3.烦人的undefined reference to
- 4.gcc "undefined reference to" 问题解决方法
- 5.Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别
1.linux下查找库文件所在位置
ldconfig -p | grep libcrypto
- glibc的库版本号查询
因为ldd命令也是glibc提供的,所以也能查看
ldd --version
2.如何查看库里面包含的函数
- 使用linux系统的nm命令。很简单。在我用的时候遇到了一个问题:
(1)例如nm lib_a.so。
因此输入如下命令:
nm -Do lib_a.so
便可以看到里面的库函数了。
(2)nm libyolo.so | grep 'compute_box_iou'
U compute_box_iou
注意:U的意思本身就是undefined未定义的意思
说明:
(1)此处的.so文件时动态链接库文件。该文件时elf(Executable and Linkable Format)文件的一种,有两个符号表,“.symtab”和“.dynsym”。
(2)查看动态符号表“.dynsym”,加上-D选项;
(3)“.dynsym”只保留“.symtab”中的全局符号(global symbols);
(4)nm lib_a.so查看的“.symtab”的符号表
- ldd+可执行文件,ldd+so库
(1)
#ldd main
linux-gate.so.1 => (0xb809c000)
libc.so.6 +> /lib/tls/i686/cmov/libc.so,6 (0x7f0c000)
(2)
# ldd /usr/lib/aarch64-linux-gnu/libSM.so
linux-vdso.so.1 => (0x0000ffffb1b70000)
libICE.so.6 => /usr/lib/aarch64-linux-gnu/libICE.so.6 (0x0000ffffb1ae0000)
libuuid.so.1 => /lib/aarch64-linux-gnu/libuuid.so.1 (0x0000ffffb1ac0000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffb1970000)
/lib/ld-linux-aarch64.so.1 (0x0000ffffb1b80000)
3.烦人的undefined reference to
- 注意思想:
这是下面的guard macro用错所致!
#ifndef ZW_STACK_ARRAY
#define ZW_STACK_ARRAY
由于zwlist.h中这个宏已经被定义,当你在zwlist.c包含zwlist.h之后,
#ifndef ZW_STACK_ARRAY已经不成立,所有的zwlist.c中的代码都被直接忽略
4.gcc “undefined reference to” 问题解决方法
- (1)链接时缺失了相关目标文件(.o)
测试代码如下:
然后编译。
gcc -c test.c
gcc –c main.c
得到两个 .o 文件,一个是 main.o,一个是 test.o ,然后我们链接 .o 得到可执行程序:
gcc -o main main.o
这时,你会发现,报错了:
main.o: In function `main':
main.c:(.text+0x7): undefined reference to `test'
collect2: ld returned 1 exit status
这就是最典型的undefined reference错误,因为在链接时发现找不到某个函数的实现文件,本例中test.o文件中包含了test()函数的实现,
所以如果按下面这种方式链接就没事了。
gcc -o main main.o test.o
- (2)链接时缺少相关的库文件(.a/.so)
先把test.c编译成静态库(.a)文件
gcc -c test.c
ar -rcs test.a test.o
至此,我们得到了test.a文件。我们开始编译main.c
gcc -c main.c
这时,则生成了main.o文件,然后我们再通过如下命令进行链接希望得到可执行程序。
gcc -o main main.o
你会发现,编译器报错了:
/tmp/ccCPA13l.o: In function `main':
main.c:(.text+0x7): undefined reference to `test'
collect2: ld returned 1 exit status
其根本原因也是找不到test()函数的实现文件,由于该test()函数的实现在test.a这个静态库中的,
故在链接的时候需要在其后加入test.a这个库,链接命令修改为如下形式即可。
gcc -o main main.o ./test.a //注:./ 是给出了test.a的路径
- (3)链接的库文件中又使用了另一个库文件
从上图可以看出,main.c调用了test.c的函数,test.c中又调用了fun.c的函数。
首先,我们先对fun.c,test.c,main.c进行编译,生成 .o文件。
gcc -c func.c
gcc -c test.c
gcc -c main.c
然后,将test.c和func.c各自打包成为静态库文件。
ar –rc func.a func.o
ar –rc test.a test.o
这时,我们准备将main.o链接为可执行程序,由于我们的main.c中包含了对test()的调用,
因此,应该在链接时将test.a作为我们的库文件,链接命令如下。
gcc -o main main.o test.a
这时,编译器仍然会报错,如下:
test.a(test.o): In function `test':
test.c:(.text+0x13): undefined reference to `func'
collect2: ld returned 1 exit status
就是说,链接的时候,发现我们的test.a调用了func()函数,找不到对应的实现。
由此我们发现,原来我们还需要将test.a所引用到的库文件也加进来才能成功链接,因此命令如下。
gcc -o main main.o test.a func.a
- (4)多个库文件链接顺序问题
这种问题也非常的隐蔽,不仔细研究你可能会感到非常地莫名其妙。
我们依然回到第(3)小节所讨论的问题中,在最后,如果我们把链接的库的顺序换一下,看看会发生什么结果?
gcc -o main main.o func.a test.a
我们会得到如下报错.
test.a(test.o): In function `test':
test.c:(.text+0x13): undefined reference to `func'
collect2: ld returned 1 exit status
因此,我们需要注意,在链接命令中给出所依赖的库时,需要注意库之间的依赖顺序,
依赖其他库的库一定要放到被依赖库的前面,这样才能真正避免undefined reference的错误,完成编译链接。
越是调用别人的越上层的库,就越放在前面。
- (5)在c++代码中链接c语言的库
如果你的库文件由c代码生成的,则在c++代码中链接库中的函数时,也会碰到undefined reference的问题。
下面举例说明。
首先,编写c语言版库文件:
编译,打包为静态库:test.a
gcc -c test.c
ar -rcs test.a test.o
至此,我们得到了test.a文件。下面我们开始编写c++文件main.cpp
然后编译main.cpp生成可执行程序:
g++ -o main main.cpp test.a
会发现报错:
/tmp/ccJjiCoS.o: In function `main':
main.cpp:(.text+0x7): undefined reference to `test()'
collect2: ld returned 1 exit status
原因就是main.cpp为c++代码,调用了c语言库的函数,因此链接的时候找不到.
解决方法:即在main.cpp中,把与c语言库test.a相关的头文件包含添加一个extern "C"的声明即可。
例如,修改后的main.cpp如下:
g++ -o main main.cpp test.a
再编译会发现,问题已经成功解决。
5.Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别
- Linux gcc编译时,的动态库搜索路径动态库的搜索路径顺序如下(注意不会递归性地在其子目录下搜索):
1、gcc编译、链接命令中的-L选项;
2、gcc的环境变量的LIBRARY_PATH(多个路径用冒号分割);
3、gcc默认动态库目录:/lib:/usr/lib:usr/lib64:/usr/local/lib。
- Linux gcc链接时,为了生成可执行二进制文件,动态库搜索路径如下:
1、编译目标代码时指定的动态库搜索路径:用选项-Wl,rpath和include指定的动态库的搜索路径,比如gcc -Wl,
-rpath,include -L. -ldltest hello.c,在执行文件时会搜索路径`./include`;
2、环境变量LD_LIBRARY_PATH(多个路径用冒号分割);
3、在 /etc/ld.so.conf.d/ 目录下的配置文件指定的动态库绝对路径(通过ldconfig生效,一般是非root用户时使用);
4、gcc默认动态库目录:/lib:/usr/lib:usr/lib64:/usr/local/lib等。
- 参考:
gcc "undefined reference to" 问题解决方法
C++ 使用动态链接库xx.so 时出现undefined reference错误
烦人的undefined reference to...
linux下查找库文件所在位置
"undefined reference to" 问题解决方法
如查看库里面包含的函数
"undefined reference to" 问题汇总及解决方法
gcc 库的链接顺序问题
Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别