undefined reference to `inflateInit_'|编译错误的诡异解决办法

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

   undefined reference to `inflateInit_'|

    inflateInit是zlib库的一个函数,这里编译错误为何会变为inflateInit_呢?我检查了我的包含头文件路径和lib文件,都设置好了,为何会出现这个错误呢?后来很偶然的想到是不是链接库的顺序问题,就改了下顺序,将下图的:

    undefined reference to `inflateInit_'|编译错误的诡异解决办法
    
   修改为下图:

undefined reference to `inflateInit_'|编译错误的诡异解决办法

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

  我的编译环境为:Win xp + sp2,CodeBlocks10.05,编译器为mingw32gcc。

6 个解决方案

#1


LZ把这个配置改到前面的那种,然后clean工程再编译试试

有时IDE总是忘记重新编译或链接库

#2


很正常三, gcc 从前到后在各个符号, 找不到就报错, 又不会往前面去找..
不喜欢就在编译选项就用 -Xlinker "-("   $(LIBS)   -Xlinker "-)"  不过这样链接的速度好慢的说..

#3


引用 1 楼 cxsjabcabc 的回复:
LZ把这个配置改到前面的那种,然后clean工程再编译试试

有时IDE总是忘记重新编译或链接库


     兄弟,不是这样的,我重新编译也是一样的错误,就是必须改变链接库的顺序的。

#4


引用 2 楼 mlee79 的回复:
很正常三, gcc 从前到后在各个符号, 找不到就报错, 又不会往前面去找..
不喜欢就在编译选项就用 -Xlinker "-("   $(LIBS)   -Xlinker "-)"  不过这样链接的速度好慢的说..


   不太明白你说的。找符号嘛,肯定得在所有库找。比如我找sin这个函数符号,我链接了a、b、c这三个库,无论如何都必须在a、b、c这三个库找一遍吧,既然如此,那么跟链接的先后顺序有关系吗?

#5


当然有关系, 谁告诉你找什么符号都会在所有的库里搜索一遍的, GNU ld 缺省的只会在用到这个符号之后的库里面去找这个符号, 除非你加上 -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



前一个不加 -Xlinker 就链接不到 f3 , 加上就没有问题..

#6


该回复于2012-06-26 16:34:52被版主删除

#1


LZ把这个配置改到前面的那种,然后clean工程再编译试试

有时IDE总是忘记重新编译或链接库

#2


很正常三, gcc 从前到后在各个符号, 找不到就报错, 又不会往前面去找..
不喜欢就在编译选项就用 -Xlinker "-("   $(LIBS)   -Xlinker "-)"  不过这样链接的速度好慢的说..

#3


引用 1 楼 cxsjabcabc 的回复:
LZ把这个配置改到前面的那种,然后clean工程再编译试试

有时IDE总是忘记重新编译或链接库


     兄弟,不是这样的,我重新编译也是一样的错误,就是必须改变链接库的顺序的。

#4


引用 2 楼 mlee79 的回复:
很正常三, gcc 从前到后在各个符号, 找不到就报错, 又不会往前面去找..
不喜欢就在编译选项就用 -Xlinker "-("   $(LIBS)   -Xlinker "-)"  不过这样链接的速度好慢的说..


   不太明白你说的。找符号嘛,肯定得在所有库找。比如我找sin这个函数符号,我链接了a、b、c这三个库,无论如何都必须在a、b、c这三个库找一遍吧,既然如此,那么跟链接的先后顺序有关系吗?

#5


当然有关系, 谁告诉你找什么符号都会在所有的库里搜索一遍的, GNU ld 缺省的只会在用到这个符号之后的库里面去找这个符号, 除非你加上 -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



前一个不加 -Xlinker 就链接不到 f3 , 加上就没有问题..

#6


该回复于2012-06-26 16:34:52被版主删除