GCC报错:could not read symbols: Archive has no index;

问题描述: 

今天在复习C的链接(静态链接,动态链接,混合链接)的时候出现了一点小问题,事情起因是这样的,我先熟悉了一下动态库的编译以及调用指令。

gcc -o libhello.so -fPIC -shared hello.c

gcc -o main main.c -L./ -lhello

LD_LIBRARY_PATH=/home/Desktop/helloworld ./main

然后能够成功调用,于是我将so文件删除之后准备尝试一下打包静态库

ar crv libhello.a hello.c

命令执行之后,确实也是成功生成了静态库文件libhello.a,但是接下来我去调用的时候就发现不对劲了

gcc -o main2 main.c -L./ -lhello

./main2

当我运行main2的时候出现了报错:

/usr/bin/ld: /home/chenqi/Desktop/helloworld/libhello.a: error adding symbols: archive has no index; run ranlib to add one
collect2: error: ld returned 1 exit status

于是我根据报错信息在网上搜寻解决办法,尝试了很多办法都没有反应,最后是看到了有位大佬的文章我才明白我哪里出现了错误。点这里

我再检查了我的静态库文件是否可用的时候突然发现,我打包的文件是hello.c而不是hello.o,于是我重新将hello.o打包后发现后续运行就不会出现报错了。

ar crv libhello.a hello.o

gcc -o main2 main.c -L./ -lhello

./main2

原因分析:

那为什么会出现这种情况呢,明明动态库可以用*.c打包而到了静态库就不行了呢。后来去查阅了资料才知道原因。

  1. 动态库的编译和链接特性

    • 编译动态库时,会生成一个包含编译后代码和符号信息的 .so 文件。这个文件在运行时被动态加载到内存中,因此需要包含完整的编译后的二进制代码和符号信息。
    • 链接动态库时,动态链接器(如 ld.so)能够在程序运行时正确地加载和链接动态库,因为动态库本身就是一个完整的可执行二进制文件。
  2. 静态库的编译和链接特性

    • 编译静态库时,使用 ar 命令将多个编译后的目标文件(.o 文件)打包成一个 .a 文件。这个过程仅仅是将多个目标文件打包在一起,不包含编译后的二进制代码和符号信息。
    • 链接静态库时,链接器需要从静态库中提取编译后的目标文件,然后将它们与主程序或其他目标文件链接在一起形成最终的可执行文件。因此,静态库在 ar 命令时必须使用编译后的 .o 文件,而不是源文件 .c

总结来说就是动态库和静态库在编译时的处理方式不同,动态库需要包含完整的编译后二进制代码和符号信息,因此可以直接使用源文件(.c 文件)进行编译。而静态库在编译时只是打包了编译后的目标文件,需要在链接时提供这些目标文件,所以必须使用编译后的 .o 文件来创建静态库。

至此,如果你的问题也是和我一样没有弄清楚动态库和静态库的不同的编译处理方式的话,那问题应该解决了,如果没有,欢迎讨论!

  • 21
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值