• 从一个链接错误探究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大侠!





     


  • 相关阅读:
    小数的进制转换
    水题 O
    水题 J
    水题T,二进制转16进制
    水题B
    水题C
    HDU 2042
    HDU 2041
    Index For SQL Server
    Learning Note For Angular
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470851.html
Copyright © 2020-2023  润新知