打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用静态库链接程序

  •  

    先关注两个gcc编译选项:

    -c 编译且汇编,但是不链接

    -S 只编译,不汇编也不链接

    -c选项产出的就是经常看到的.o文件,也是一般用来创建静态库的文件。

    用如下的命令可以将多个.o文件打包为一个静态库文件:ar crs libtest.a src/test1.o src/test2.o

    现在完成了静态库创建工作,我们怎么在链接一个可执行程序的时候使用这个静态库呢?

    有三种方式:

    1. gcc -o test main.c libtest.a

    2. gcc -o test main.c –ltest –L./

    3. gcc -o test main.c -Xlinker “-(” libtest.a -Xlinker “-)”

    其中一、二其实是同一种使用方式,第三种方式稍有不同,这个不同之处是什么呢?

    第三种方式其实是多传了两个参数给链接器:”-(”和”-)”。传这个两个参数有什么作用吗?

    上面的使用中还看不出来传给链接器的两个参数的作用。

    但是假设我们需要用到两个静态库:libtest1.a和libtest2.a,其中libtest2.a中又使用了libtest1.a中的接口

    那么我们可以这样使用:(原来三种使用方式中的1、2其实是一种,后面只列出其中之一)

    1. gcc –o test main.c libtest2.a libtest1.a

    2. gcc -o test main.c -Xlinker “-(” libtest1.a libtest2.a -Xlinker “-)”

    需要注意的是:第一种使用方式中静态库出现的顺序,libtest2.a必须在libtest1.a之前,否则会有”undefined reference to ***”的链接错误,其中***就是libtest2.a中使用的libtest1.a的接口。

    如果libtest1.a在前,为什么会有链接错误呢?

    原因是gcc在链接的时候,对于多个静态库或者.o文件是从前往后依次处理的,如果当前的静态库或.o文件中没有使用的符号,则往后继续寻找,而不会再往前查找。

    下面是man gcc看到的说明:

    Java代码  
    1. -l library  
    2.            Search the library named library when linking.  (The second alternative with the library as a separate argument is  
    3.            only for POSIX compliance and is not recommended.)  
    4.     
    5.            It makes a difference where in the command you write this option; the linker searches and processes libraries and  
    6.            object files in the order they are specified.  Thus, foo.o -lz bar.o searches library z after file foo.o but before  
    7.            bar.o.  If bar.o refers to functions in z, those functions may not be loaded.  

     所以在使用一些依赖关系比较复杂的静态库时,我们可能会看到这样的使用方式:gcc –o test main.c libtest1.a libtest2.a libtest1.a。在链接序列中,一个静态库可能出现多次,以解决一些循环依赖。

    那么如果是gcc -o test main.c -Xlinker “-(” libtest1.a libtest2.a -Xlinker “-)”的使用方式,还需要考虑顺序么?

    答案是不需要。

    因为Xlinker选项是将参数传给链接器,而man ld我们可以看到这样一段说明:

    Java代码  
    1. -( archives -)  
    2.        --start-group archives --end-group  
    3.            The archives should be a list of archive files.  They may be either explicit file names, or -l options.  
    4.     
    5.            <strong>The specified archives are searched repeatedly until no new undefined references are created.</strong>  Normally, an archive is  
    6.            searched  only  once  in the order that it is specified on the command line.  If a symbol in that archive is needed to  
    7.            resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the  linker  
    8.            would not be able to resolve that reference.  By grouping the archives, they all be searched repeatedly until all pos-  
    9.            sible references are resolved.  
    10.     
    11.            Using this option has a significant performance cost.  It is best to use it only when there are  unavoidable  circular  
    12.            references between two or more archives.  

     链接器在处理”-(”和”-)”之间的静态库时,是会重复查找这些静态库的,所以就解决了静态库查找顺序问题。不过,man里面也说明了,这种方式比人工提供了链接顺序的方式效率会低很多。


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux下静态链接库和动态链接库的使用
Linux静态链接(库)、动态链接(库)、可执行文件加载相关问题(创建、选项、环境变量等)
用 Cython 包装静态库和动态库
程序运行时,是怎么找到动态库的?
gcc创建和使用静态库、动态库
把共享库(SO)加载到指定的内存地址
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服