zoukankan      html  css  js  c++  java
  • 从一个链接错误探究GCC的链接库顺序

    作者:朱金灿

    来源:http://blog.csdn.net/clever101

     

              使用CodeBlocks10.05编一个小程序用到了png库和zlib库。我发现编译png静态库时,只需要指定zlib库的头文件路径,但并不需要链接到zlib库(这个我感觉有点奇怪)。 然后编译自己写的程序时出现一个错误:

      undefined reference to `inflateInit_'|

            inflateInit是zlib库的一个函数,这里编译错误显示为inflateInit_(我估计是gcc给函数添加了修饰符的缘故)。我检查了我的包含头文件路径和lib文件,都设置好了,为何会出现这个错误呢?后来很偶然的想到是不是链接库的顺序问题,就改了下顺序,将下图的:

               

                          

         

            修改为下图:

                         

           

             即把png库提到zlib库的前面然后重新编译这个编译错误就消失了。这是为什么呢?


           上论坛求教,mLee79大侠告诉我:gcc 从前到后在各个符号,找不到就报错, 又不会往前面去找。如果不想安排链接顺序,就在编译选项添加 -Xlinker "-("$(LIBS) -Xlinker "-)"。一个简单的例子是:

         

    $ for file in app.c f1.c f2.c f3.c ; do echo ---- $file ; cat $file ; done ;  gcc -c f1.c f2.c f3.c ; \
      ar crf lib1.a f1.o f3.o ; ar crf lib2.a f2.o ;  gcc app.c lib1.a lib2.a ; \
      gcc app.c -Xlinker "-(" lib1.a lib2.a -Xlinker "-)"
    ---- app.c
    int main()
    {
            extern int f1( int , int );
            extern int f2( int , int );
            return f1( 1 , 2 ) + f2( 3, 4 );
    }
    ---- f1.c
    int f1( int a , int b ) { return a + b; }
    ---- f2.c
    extern int f3( int , int );
    int f2( int a , int b ) { return a * b - f3( a , b ); }
    ---- f3.c
    int f3( int a , int b ) { return a - b; }
    
    lib2.a(f2.o):f2.c:(.text+0x1e): undefined reference to `_f3'
    collect2: ld returned 1 exit status
    

          

            这里简单说明下这个例子:程序首先链接的lib1(f3符号在lib1),当程序链接到lib2时,很自然就找不到f3(因为lib1在lib2的前面),

     

            不过可以想象加 -Xlinker肯定很慢,因为每个符号都要查找所有的库。因此要解决此类链接错误还是得安排链接库的顺序,遵循的原则是上层调用库放在底层被调用库的前面。在此非常感谢mLee79大侠!





     


  • 相关阅读:
    软件杯_视频全量目标分析和建模_初步分析
    《一线架构师实践指南》第三部分阅读笔记
    eclipse配置Struts2至Tomcat8.5
    《一线架构师实践指南》阅读笔记02
    Java中对list集合使用HashSet去重不成功
    学习02
    《一线架构师实践指南》阅读笔记01
    通过DOS命令将txt文件导入mysql数据库
    zookeeper集群环境搭建详细图文教程
    SSO之CAS单点登录详细搭建教程
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470851.html
Copyright © 2011-2022 走看看