Error when linking LibRaw to shared object

379 Views Asked by At

So, what i'm actually trying to is to build a shared object, that contains a python-includable-module, generated by pybind11. I got it as far as to have no syntax-errors in CLion, but when i try to compile it, it gives the following error:

/usr/bin/ld: //usr/local/lib/libraw.a(utils_libraw.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
CMakeFiles/cr3_to_python.dir/build.make:98: recipe for target 'cr3_to_python.cpython-36m-x86_64-linux-gnu.so' failed
make[3]: *** [cr3_to_python.cpython-36m-x86_64-linux-gnu.so] Error 1
CMakeFiles/Makefile2:77: recipe for target 'CMakeFiles/cr3_to_python.dir/all' failed
make[2]: *** [CMakeFiles/cr3_to_python.dir/all] Error 2
CMakeFiles/Makefile2:84: recipe for target 'CMakeFiles/cr3_to_python.dir/rule' failed
make[1]: *** [CMakeFiles/cr3_to_python.dir/rule] Error 2
Makefile:118: recipe for target 'cr3_to_python' failed
make: *** [cr3_to_python] Error 2

When compiling with c++ i get something very similar:

$ c++ -O3 -Wall -shared -std=c++11 -fPIC -I/usr/include/python3.6m/ -I/usr/local/include/opencv4/ $(python3 -m pybind11 --includes) main.cpp -o cr3_to_python$(python3-config --extension-suffix) -lraw
/usr/bin/ld: //usr/local/lib/libraw.a(utils_libraw.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

What annoys me the most is the actual error:

/usr/bin/ld: //usr/local/lib/libraw.a(utils_libraw.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC

Because i didn't include anything related to stderr (from my point of view) in the code.

main.cpp

CMakeLists.txt

1

There are 1 best solutions below

0
On BEST ANSWER

When compiling a shared library on Linux and Macos (and probably other Unixy OSes) all code used in the library needs to be compiled in "position independent mode", this is because the compiler doesn't know where an executable will load your code so has to generate code which can be run from any address.

To generate PIC code you need to pass the -fPIC flag to GCC.

Note that all the code you want to compile into your shared library needs to be compiled in PIC mode, this includes code in static libraries. In your case you need to recompile libraw.a with -fPIC enabled.

Position independent code might be slightly slower but the difference is small so you can probably just compile all your code with -fPIC even if its being used directly in an executable. Apple recommends that all code including executables is position independent. See How much overhead can the -fPIC flag add? for more details about performance.