Reputation: 58
I've reduced the problem to this minimal 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. So what gives?
(Output above is from Ubuntu 17.10 with libpng16. Ubuntu 16.04 with libpng12 results in similar error.)
Upvotes: 3
Views: 3339
Reputation: 359
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.
It also solves problem when compiling blender on Linux as a Python module:
/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
Upvotes: 3
Reputation: 180103
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. 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. That's what it wants you to recompile with -fPIC
.
Although it is possible to store PIC objects in a regular archive such as libpng16.a
, that is unconventional. 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. You should not expect any such archives provided by standard packages to contain PIC objects.
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. 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.
Upvotes: 1