将 LibRaw 链接到共享对象时出错

Error when linking LibRaw to shared object

所以,我实际上想要构建一个共享对象,其中包含一个由 pybind11 生成的 python-includable-module。据我所知,在 CLion 中没有语法错误,但是当我尝试编译它时,它给出了以下错误:

/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

当用 C++ 编译时,我得到了非常相似的东西:

$ 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

最让我烦恼的是实际错误:

/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

因为我没有在代码中包含任何与 stderr 相关的内容(从我的角度来看)。

main.cpp

CMakeLists.txt

在 Linux 和 Macos(可能还有其他 Unixy 操作系统)上编译共享库时,库中使用的所有代码都需要在 "position independent mode" 中编译,这是因为编译器不会知道在哪里和可执行文件将加载您的代码,因此必须从任何地址生成可以 运行 的代码。

要生成 PIC 代码,您需要将 -fPIC 标志传递给 GCC。

请注意,所有要编译到共享库中的代码都需要在PIC 模式下编译,这包括静态库中的代码。在您的情况下,您需要在启用 -fPIC 的情况下重新编译 libraw.a

与位置无关的代码可能会稍微慢一些,但差异很小,因此即使直接在可执行文件中使用,您也可以使用 -fPIC 编译所有代码。 Apple 建议包括可执行文件在内的所有代码都与位置无关。有关性能的更多详细信息,请参阅 How much overhead can the -fPIC flag add?