繁体   English   中英

静态链接 libpng 到共享库

[英]Static link libpng into a shared library

我已将问题简化为这个最小的 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 重新编译”,但是正如您所看到的,我已经在这样做了。 那么什么给呢?

(上面的输出来自带有 libpng16 的 Ubuntu 17.10。带有 libpng12 的 Ubuntu 16.04 导致类似的错误。)

现在,我找到的关于该错误的每个答案都可以归结为“按照所说的做,然后使用-fPIC重新编译”,但是正如您所看到的,我已经在这样做了。 那有什么呢?

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

尽管可以将PIC对象存储在常规归档文件(例如libpng16.a ,但这是非常规的。 并非没有理由将这些文件称为“静态库”。 通常,它们旨在支持构建静态二进制文件,而不是共享二进制文件,并且PIC对象无法实现该目的。 您不应期望标准软件包提供的任何此类归档文件都包含PIC对象。

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

使用 -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

你的二进制文件在~/Documents/libpng/libpng-1.6.37/lib ,最有趣的是libpng.a ,它现在是用 -fPIC 编译的。

它还解决了在 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