c++ - 将 LibRaw 链接到共享对象时出错
问题描述
所以,我实际上想要构建一个共享对象,它包含一个由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 相关的任何内容(从我的角度来看)。
解决方案
在 Linux 和 Macos(可能还有其他 Unixy 操作系统)上编译共享库时,库中使用的所有代码都需要在“位置无关模式”下编译,这是因为编译器不知道可执行文件将在哪里加载您的代码,所以必须生成可以从任何地址运行的代码。
要生成 PIC 代码,您需要将-fPIC
标志传递给 GCC。
请注意,您要编译到共享库中的所有代码都需要在 PIC 模式下编译,这包括静态库中的代码。libraw.a
在您的情况下,您需要-fPIC
启用重新编译。
与位置无关的代码可能会稍微慢一些,但差异很小,因此-fPIC
即使直接在可执行文件中使用,您也可以编译所有代码。Apple 建议所有代码(包括可执行文件)都与位置无关。请参阅-fPIC 标志可以增加多少开销?有关性能的更多详细信息。
推荐阅读
- javascript - 推送在 Firebase 侦听器中不起作用
- java - Java: ZonedDateTime - 获取参考时间戳的偏移量
- amazon-ec2 - 在 AWS 中重命名 EC2 实例
- angular - 从 Angular 应用程序调用共享点 REST API
- java - 收到蓝牙字符串的问题
- android - 同一EditText中的不同键盘 - Android
- c# - 调用 Ebay API 时,Content-Language 标头会引发 Misused header name 错误
- java - RxJava:令人费解的行为
- amazon-web-services - 增加和减少 AWS CloudWatch 图表
- java - Junit Mockito 将 SessionFactory 模拟成 DAO 测试类