编译失败,因为在创build共享对象时不能使用“.rodata.str1.8”的重定位R_X86_64_32“
我试图从VPS中的makefile编译这个源代码,但它不工作。 VPS是一个64分的操作系统
这是完整的错误
# 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
任何人都知道什么是错的?
做编译器告诉你做什么,即用-fPIC
重新编译。 要了解这个标志是做什么的,为什么在这种情况下需要它,请参阅GCC手册的代码生成选项 。
简言之, 位置独立码 (PIC)是指所生成的机器码,其是不依赖于存储器地址的,也就是说,不对其被装载到RAM中的位置做出任何假设。 只有位置独立的代码应该包含在共享对象(SO)中,因为它们应该有能力dynamic地改变它们在RAM中的位置。
最后,你也可以在维基百科上阅读它。
在我的情况下,出现这个错误是因为make
命令期望从LDFLAGS
环境variables指示的远程目录中获取共享库( *.so
文件)。 有一个错误,只有静态库可用( *.la
或*.a
文件)。
因此,我的问题并没有与我正在编译的程序,而是与它试图获取的远程库。 所以,我不需要添加任何标志(比如-fPIC
)到由重定位错误中断的编译。 相反,我重新编译远程库,以便共享对象可用。
基本上,这是一个伪装文件未发现的错误。
在我的情况下,我不得不在必要的程序的configure
调用中删除错误的--disable-shared
开关,因为共享和静态库都是默认构build的。
我注意到,大多数程序同时build立两种types的库,所以我的可能是一个angular落的情况。 通常情况下,您可能需要启用共享库,具体取决于默认值。
用编译开关和默认值来检查你的特定情况,我会读出用./configure --help | less
显示的总结./configure --help | less
./configure --help | less
,通常在可选function部分。 我经常发现这个阅读比依赖程序发展时没有更新的安装指南更可靠。
它并不总是关于编译标志,我使用distcc时在gentoo上有同样的错误。
原因是在distcc服务器上使用的是未经过强化的configuration文件,而在客户端上configuration文件已经过硬化。 检查这个讨论: https : //forums.gentoo.org/viewtopic-p-7463994.html