重定位 R_X86_64_PC32 对符号 _ZTISt13runtime_error@@GLIBCXX_3.4 在制作共享对象时不能使用;使用 -fPIC 重新编译

Posted

技术标签:

【中文标题】重定位 R_X86_64_PC32 对符号 _ZTISt13runtime_error@@GLIBCXX_3.4 在制作共享对象时不能使用;使用 -fPIC 重新编译【英文标题】:relocation R_X86_64_PC32 against symbol _ZTISt13runtime_error@@GLIBCXX_3.4 can not be used when making a shared object; recompile with -fPIC 【发布时间】:2018-07-26 21:10:54 【问题描述】:

我尝试编译的项目并不复杂,只引用标准库和一个自包含库(一切都可以在另一个系统上编译)。如标题所示,它甚至无法链接到标准库中的某些内容,因为据说那里的内容没有使用-fPIC 编译。我自己没有构建它,也不想构建它,并且使用 apt 重新安装东西似乎无法解决“使用 -fPIC 重新编译”问题。

我会说我认为问题的一个可能来源是由于gcc-multilib 或之前安装的东西,但我认为这已被清除。我不知道,也许某些内容被覆盖或发生了冲突。甚至可能没有关系。有什么想法吗?

运行 Ubuntu 18.04

g++ -I inc -I /usr/include/mono-2.0 -MMD -MF dep/Nonsense.d -std=c++17 -O3 -fno-stack-protector -fno-unroll-loops -fomit-frame-pointer -Wno-ignored-optimization-argument -c -o obj/Nonsense.o src/Nonsense.cpp
g++ -I inc -I /usr/include/mono-2.0 -MMD -MF dep/Socket.d -std=c++17 -O3 -fno-stack-protector -fno-unroll-loops -fomit-frame-pointer -Wno-ignored-optimization-argument -c -o obj/Socket.o src/Socket.cpp
g++ -shared -flto -o libNonsense.so obj/Nonsense.o obj/Socket.o -Llib -lenet
/usr/bin/x86_64-linux-gnu-ld: obj/Socket.o: relocation R_X86_64_PC32 against symbol `_ZTISt13runtime_error@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/bin/x86_64-linux-gnu-ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
makefile:22: recipe for target 'libNonsense.so' failed
make: *** [libNonsense.so] Error 1

【问题讨论】:

这是窗户吗? 缺少太多信息。我们需要了解平台、您的配置方式、典型命令行、链接器命令等。如果我们知道具体细节,PKG_CONFIG_PATH 可能会解决问题。 我已经添加了更多的上下文,除了配置,因为这个项目非常简单,g++ 的简单命令就足以构建它。我感觉有些东西安装不正确,因为编译这么简单的东西应该不会导致这样的问题。 请告诉我们你用来构建obj/Socket.o的命令。 您需要按照错误消息中的说明进行操作。在编译源代码文件时添加 -fPIC 标志,并在创建(链接)libNonsense.so 库时添加 -fPIC 【参考方案1】:

正如错误消息所说,您需要使用-fPIC重新编译。您当前的编译器命令未显示 -fPIC 选项:

g++ -I inc -I /usr/include/mono-2.0 -MMD -MF dep/Socket.d -std=c++17 -O3 -fno-stack-protector -fno-unroll-loops -fomit-frame-pointer -Wno-ignored-optimization-argument -c -o obj/Socket.o src/Socket.cpp

顺便说一句,-flto 也一样——这个标志也必须在编译时指定才能生效。

【讨论】:

这几乎可以概括。 奇怪,我以前这样做过,但不知何故不起作用,但现在可以了。也许清理过程不知何故没有删除旧的目标文件。我在各处都添加了 fPIC 标志,但它不起作用,但现在似乎已经解决了。 @Florian Weimer 我也在使用 g++,我遇到了同样的错误。 ***.com/questions/61404608/…请查收

以上是关于重定位 R_X86_64_PC32 对符号 _ZTISt13runtime_error@@GLIBCXX_3.4 在制作共享对象时不能使用;使用 -fPIC 重新编译的主要内容,如果未能解决你的问题,请参考以下文章

内联程序集返回:在创建共享对象时,不能使用针对未定义符号的重定位R_X86_64_32S [重复]

重定位 R_X86_64_32S 对 `.data' 在制作共享对象时不能使用;使用 gcc 重新编译 -fPIC

“重定位 R_X86_64_32S 反对”链接错误

为什么在创建特定于x86_64的共享对象时“无法使用R_X86_64_32”的CMake解决方案?

位置无关代码的区别:x86 vs x86-64

relocation R_X86_64_32S against `.data‘ can not be used when making a PIE object; recompile with -fP