编译失败时"在制作共享对象时不能使用"重定位R_X86_64_32对`.rodata.str1.8'"

use*_*191 71 c++ linux linker gcc shared-libraries

我正在尝试从VPS中的makefile编译此源代码,但它不起作用.VPS是64 Cent OS

这是完整的错误

# make
gcc -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/amx/*.c
g++ -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/*.cpp
g++ -c -O3 -w -DLINUX -I../SDK/amx/ *.cpp
g++ -O2 -fshort-wchar -shared -o "TCP_V1.so" *.o
/usr/bin/ld: TCP-LINUX_V1.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be     used when making a shared object; recompile with -fPIC
TCP-LINUX_V1.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [all] Error 1
Run Code Online (Sandbox Code Playgroud)

这是我的makefile:

GPP=g++
GCC=gcc
OUTFILE="TCP_V1.so"

COMPILE_FLAGS=-c -O3 -w -DLINUX -I../SDK/amx/

all:
    $(GCC) $(COMPILE_FLAGS) ../SDK/amx/*.c
    $(GPP) $(COMPILE_FLAGS) ../SDK/*.cpp
    $(GPP) $(COMPILE_FLAGS) *.cpp
    $(GPP) -O2 -fshort-wchar -shared -o $(OUTFILE) *.o
Run Code Online (Sandbox Code Playgroud)

谁知道什么是错的?

Ale*_*aev 110

执行编译器告诉您的操作,即重新编译-fPIC.要了解此标志的作用以及在这种情况下您需要它的原因,请参阅GCC手册的代码生成选项.

简而言之,术语位置无关代码(PIC)是指生成的机器代码,它与内存地址无关,即不对其加载到RAM的位置做任何假设.只有位置无关的代码应该包含在共享对象(SO)中,因为它们应该能够动态地改变它们在RAM中的位置.

最后,你也可以在维基百科上阅读它.

  • @Beni Bogosel:这很简单.您只需将`-fPIC`添加到库的所有源文件(转换单元,例如`*.cpp`文件)的所有编译器调用中.这样做的具体方法取决于您使用的构建系统.例如,在CMake中,您可以发出`set_target_properties($ {LIBRARY_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)`.如果这个人(使用普通的Make),他将不得不做`COMPILE_FLAGS + = - fPIC`,因为他使用这个变量来表示他的库的所有源文件的编译标志集. (11认同)
  • 你能解释一下如何用-fPIC重新编译吗? (3认同)

Xav*_*uvw 41

在我的情况下发生此错误是因为make命令期望*.soLDFLAGS环境变量指示的远程目录中获取共享库(文件).在一个错误中,只有静态库可用(*.la*.a文件).

因此,我的问题不在于我正在编译的程序,而在于它正在尝试获取的远程库.所以,我不需要-fPIC在重定位错误中断的编译中添加任何标志(例如).相反,我重新编译了远程库,以便共享对象可用.

基本上,它是伪装的文件未找到的错误.

在我的情况下,我必须在必要程序--disable-sharedconfigure调用中删除一个错位的开关,因为共享和静态库都是默认构建的.


我注意到大多数程序同时构建了两种类型的库,因此我的可能是一个极端情况.通常,您可能需要启用共享库,具体取决于默认值.

要使用编译开关和默认值检查您的特定情况,我会读出显示的摘要./configure --help | less,通常在可选功能部分中.我经常发现这种读取比依赖程序发展时未更新的安装指南更可靠.

  • 完美,“这是一个伪装的文件未找到错误。” 在我的情况下,依赖项尚未安装。 (2认同)

小智 16

-no-pie在链接器阶段使用选项修复它:

g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...
Run Code Online (Sandbox Code Playgroud)


EII*_*PII 10

它并不总是关于编译标志,我在使用distcc时在gentoo上有相同的错误.

原因是,在distcc服务器上使用的是未强化的配置文件,并且在客户端上,配置文件已经过强化.请查看此讨论:https: //forums.gentoo.org/viewtopic-p-7463994.html