静态链接libpng到共享库中

时间:2017-10-27 17:33:19

标签: c shared-libraries static-libraries ld static-linking

我已将问题减少到这个最小的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导致类似的错误。)

1 个答案:

答案 0 :(得分:1)

  

现在,我发现此错误的每个答案归结为"执行它所说的内容并使用-fPIC"重新编译,但正如您所看到的,我已经这样做了。那是什么给出了什么?

正如我评论的那样,不,实际上你已经已经这样做了。链接器希望从libpng16.a链接的对象是PIC,而它们不是。 那是它希望您使用-fPIC重新编译的内容。

尽管可以将PIC对象存储在libpng16.a这样的常规存档中,但这是非常规的。这些文件经常被称为静态库"并非没有理由。它们通常用于支持构建静态二进制文件,而不是共享库,而PIC目标不支持这种目的。您不应期望标准软件包提供的任何此类存档包含PIC对象。

无论如何,由于您正在构建共享库,因此自然而恰当的做法是链接到libpng的共享版本。您尝试链接静态库时遇到了一些麻烦,但目前尚不清楚原因。无论你想要完成什么,这都是错误的方式,即使它是值得完成的事情。