Linux的链接:'-lpng'禁止'-lz'?

在ubuntu-13.04上,使用linux发行版提供的GCC-4.7.3从共享库构build可执行文件时出错。

我猜这个问题是libpng和zlib(前者使用后者),但我不知道为什么。

首先,我的命令是:

$ gfortran -o test_muesli_config_fml test_muesli_config_fml.o -fopenmp -Wl,--rpath,/usr/local/lib/muesli /usr/local/lib/muesli/libfml.so -lstdc++ -Wl,--rpath,/usr/lib /usr/lib/liblapack.so -Wl,--rpath,/usr/lib /usr/lib/libblas.so -lpng -lz -lpthread -lreadline -lhistory 

这给出了以下错误:

 /usr/local/lib/muesli/libfml.so: undefined reference to `gzwrite' /usr/local/lib/muesli/libfml.so: undefined reference to `gzopen' /usr/local/lib/muesli/libfml.so: undefined reference to `gzclose' /usr/local/lib/muesli/libfml.so: undefined reference to `gzread' collect2: error: ld returned 1 exit status 

但是请注意, -lz存在。 之后,我添加了链接器选项--trace-symbol=以获取更多信息:

 $ gfortran -o test_muesli_config_fml test_muesli_config_fml.o -fopenmp -Wl,--rpath,/usr/local/lib/muesli /usr/local/lib/muesli/libfml.so -lstdc++ -Wl,--rpath,/usr/lib /usr/lib/liblapack.so -Wl,--rpath,/usr/lib /usr/lib/libblas.so -lpng -lz -lpthread -lreadline -lhistory -Wl,--trace-symbol=gzwrite 

反过来给出结果:

 /usr/local/lib/muesli/libfml.so: reference to gzwrite /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libz.so: definition of gzwrite /usr/local/lib/muesli/libfml.so: undefined reference to `gzwrite' /usr/local/lib/muesli/libfml.so: undefined reference to `gzopen' /usr/local/lib/muesli/libfml.so: undefined reference to `gzclose' /usr/local/lib/muesli/libfml.so: undefined reference to `gzread' collect2: error: ld returned 1 exit status 

所以, gzwrite是在libz.sofind的,但链接器不使用它!

偶然,我想删除-lpng选项(实际上,不使用libpng库),我的问题解决了! 为什么?

其次,我用另一个版本的GCC-4.7.3编译我的整个代码(我自己编译 – 我用来testing编译器的许多版本),并且没有发生错误,即使同时使用-lpng-lz

任何想法?

另外,另一个程序(USE libpng)的另一个尝试会导致构build成功。

2013-10-08编辑

我很确定现在它是Ubuntu-13.04中的一个错误:我已经尝试了两个其他的Linux发行版(Fedora 16 – Ubuntu-10.04),并且链接器行为是标准的,不像上面第一部分信息。

我打算在Ubuntu社区上报告这个问题。 问候。

编辑于2013-10-09

该错误已经报告给https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1237270

两个可能的修复(直到Ubuntu不修复自己):

  1. 尝试在libpng.alibz.a编译为一个静态库(它可能只是一个临时解决方案,因为在大多数情况下,静态库是邪恶的)。

  2. 从原始资源重新编译libpng,并在此处将静态编译的libz.a编译为静态。