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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么在创建特定于x86_64的共享对象时“无法使用R_X86_64_32”的CMake解决方案?相关的知识,希望对你有一定的参考价值。

我为我的新玩具编译一些插件时遇到了这个错误(在Linux上的gcc / g ++上):

在制作共享对象时不能使用重定位R_X86_64_32;用-fPIC重新编译

我基本上了解why PIC is needed,但在CMake系统中,solution seems to be this

IF (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
    SET_TARGET_PROPERTIES (${PLUGIN_BASE_LIB} PROPERTIES COMPILE_FLAGS "-fPIC")
ENDIF (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")

我不明白为什么这个解决方案是有条件的。

follow-up似乎表明-fPIC应该基本上用于除32位Linux之外的所有地方,这表明上述不可移植。

我应该总是使用-fPIC吗?会有不良影响吗?

${PLUGIN_BASE_LIB}需要静态链接到主可执行文件,静态链接各种共享库作为插件。

答案

理想情况下,您希望构建两个版本的代码:一个用于主可执行文件,另一个用于库。第一个需要使用-fPIE(现代发行版中的默认值)编译,第二个需要使用-fPIC编译。正如您所指出的,这不依赖于目标架构。

您只能使用-fPIC编译一个版本,但主要可执行文件将不是最理想的,因为-fPIC强制编译器遵守符号插入规则,这极大地限制了它优化代码的能力,例如:内联和克隆功能。

以上是关于为什么在创建特定于x86_64的共享对象时“无法使用R_X86_64_32”的CMake解决方案?的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

使用“共享”选项编译 OpenSSL?

如果有的话,在 java 中声明给定类的空对象字段时会发生哪些特定于类的操作?

Unix 线程共享创建进程打开的文件资源