简体   繁体   English

静态链接 libpng 到共享库

[英]Static link libpng into a shared library

I've reduced the problem to this minimal test.c:我已将问题简化为这个最小的 test.c:

#include "png.h"

int function() {
    printf("%ld", (long)png_create_read_struct);
}

Compiling with编译

gcc -shared -fPIC test.c -o test.so -lm -l:libpng16.a

gives the error给出错误

/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

Now every answer I've found to this error boils down to "do what it says and recompile with -fPIC", but as you can see I'm already doing that.现在,我找到的针对此错误的每个答案都归结为“按照它所说的去做并使用 -fPIC 重新编译”,但是正如您所看到的,我已经在这样做了。 So what gives?那么什么给呢?

(Output above is from Ubuntu 17.10 with libpng16. Ubuntu 16.04 with libpng12 results in similar error.) (上面的输出来自带有 libpng16 的 Ubuntu 17.10。带有 libpng12 的 Ubuntu 16.04 导致类似的错误。)

Now every answer I've found to this error boils down to "do what it says and recompile with -fPIC", but as you can see I'm already doing that. 现在,我找到的关于该错误的每个答案都可以归结为“按照所说的做,然后使用-fPIC重新编译”,但是正如您所看到的,我已经在这样做了。 So what gives? 那有什么呢?

As I commented, no, in fact you're not already doing that. 正如我评论的那样,不,实际上您还没有这样做。 The linker wants the objects linked in from libpng16.a to be PIC, and they're not. 链接器希望从libpng16.a链接的对象是PIC,而不是。 That's what it wants you to recompile with -fPIC . 就是它希望您使用-fPIC重新编译的内容。

Although it is possible to store PIC objects in a regular archive such as libpng16.a , that is unconventional. 尽管可以将PIC对象存储在常规归档文件(例如libpng16.a ,但这是非常规的。 It is not without reason that these files are often called "static libraries". 并非没有理由将这些文件称为“静态库”。 They are ordinarily intended to support building static binaries, not shared ones, and that purpose is not served by PIC objects. 通常,它们旨在支持构建静态二进制文件,而不是共享二进制文件,并且PIC对象无法实现该目的。 You should not expect any such archives provided by standard packages to contain PIC objects. 您不应期望标准软件包提供的任何此类归档文件都包含PIC对象。

In any event, since you are building a shared library, the natural and appropriate thing to do would be to link to the shared version of libpng. 无论如何,由于您正在构建共享库,因此自然而适当的事情是链接到libpng的共享版本。 You've gone to some trouble to try to link the static library instead, but it is not clear why. 您遇到了麻烦,尝试改为链接静态库,但尚不清楚原因。 Whatever you're trying to accomplish, this is the wrong way to go about it, if even it's something worth accomplishing at all. 无论您要完成什么,这都是错误的方法,即使它根本值得完成。

Compiling libpng with -fPIC使用 -fPIC 编译 libpng

user@user_pc:~/Documents$ mkdir libpng
user@user_pc:~/Documents$ cd libpng
user@user_pc:~/Documents/libpng$ wget https://download.sourceforge.net/libpng/libpng-1.6.37.tar.gz
user@user_pc:~/Documents/libpng$ tar xvfz libpng-1.6.37.tar.gz
user@user_pc:~/Documents/libpng$ cd libpng-1.6.37
user@user_pc:~/Documents/libpng/libpng-1.6.37$./configure --prefix=/home/user/Documents/libpng --with-pic=yes
user@user_pc:~/Documents/libpng/libpng-1.6.37$ sudo make

Your binaries are in ~/Documents/libpng/libpng-1.6.37/lib , most interesting one is libpng.a which was now compiled with -fPIC.你的二进制文件在~/Documents/libpng/libpng-1.6.37/lib ,最有趣的是libpng.a ,它现在是用 -fPIC 编译的。

It also solves problem when compiling blender on Linux as a Python module:它还解决了在 Linux 上将 Blender 编译为 Python 模块时的问题:

/usr/bin/ld.gold: error: /usr/lib/x86_64-linux-gnu/libpng.a(pngerror.o): requires dynamic R_X86_64_PC32 reloc against 'stderr' which may overflow at runtime; recompile with -fPIC
collect2: error: ld returned 1 exit status

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM