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

时间:2013-10-14 16:38:54

标签: c++ linux gcc linker 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

这是我的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

任何人都知道什么是错的?

7 个答案:

答案 0 :(得分:103)

执行编译器要求您执行的操作,即使用-fPIC重新编译。要了解此标记的作用以及在这种情况下您需要它的原因,请参阅GCC手册的 Code Generation Options

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

最后,您也可以在 Wikipedia 上阅读相关内容。

答案 1 :(得分:35)

在我的情况下发生此错误是因为make命令期望从*.so环境变量指示的远程目录中获取共享库(LDFLAGS文件)。如果出现错误,那里只有静态库(*.la*.a文件)。

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

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

在我的情况下,我必须删除必需程序的--disable-shared调用中错误放置的configure开关,因为共享库和静态库都是默认构建的。

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

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

答案 2 :(得分:9)

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

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

答案 3 :(得分:4)

一个“干净”的东西为我解决了。

我的项目是C ++应用程序(不是共享库)。经过大量成功的构建,我随机得到了这个错误。

答案 4 :(得分:0)

我遇到了同样的问题。尝试使用-fPIC标志重新编译。

答案 5 :(得分:0)

在链接器阶段使用-no-pie选项修复了该问题:

g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...

答案 6 :(得分:0)

我得到的解决方案与@camino对https://stackoverflow.com/a/19365454/10593190XavierStuvw's reply的评论相同。

我从一开始就简单地重新安装了整个内容,将$ ./configure的所有实例都替换为$ ./configure --enable-shared(首先确保删除所有文件夹和文件,包括上一次尝试的.so文件)。

显然这可行,因为https://stackoverflow.com/a/13812368/10593190