我已将问题减少到这个最小的test.c:
#include "png.h"
int function() {
printf("%ld", (long)png_create_read_struct);
}
使用
进行编译gcc -shared -fPIC test.c -o test.so -lm -l:libpng16.a
给出错误
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libpng16.a(pngread.o): relocation R_X86_64_PC32 against symbol `png_sRGB_table' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
现在我发现这个错误的每个答案归结为“按照它说的做并用-fPIC重新编译”,但正如你所看到的那样我已经这样做了。那是什么给出了什么?
(上面的输出来自Ubuntu 17.10和libpng16。带有libpng12的Ubuntu 16.04导致类似的错误。)
答案 0 :(得分:1)
现在,我发现此错误的每个答案归结为"执行它所说的内容并使用-fPIC"重新编译,但正如您所看到的,我已经这样做了。那是什么给出了什么?
正如我评论的那样,不,实际上你已经不已经这样做了。链接器希望从libpng16.a
链接的对象是PIC,而它们不是。 那是它希望您使用-fPIC
重新编译的内容。
尽管可以将PIC对象存储在libpng16.a
这样的常规存档中,但这是非常规的。这些文件经常被称为静态库"并非没有理由。它们通常用于支持构建静态二进制文件,而不是共享库,而PIC目标不支持这种目的。您不应期望标准软件包提供的任何此类存档包含PIC对象。
无论如何,由于您正在构建共享库,因此自然而恰当的做法是链接到libpng的共享版本。您尝试链接静态库时遇到了一些麻烦,但目前尚不清楚原因。无论你想要完成什么,这都是错误的方式,即使它是值得完成的事情。