95

我正在尝试从 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

这是我的生成文件:

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

有谁知道怎么了?

4

8 回答 8

126

做编译器告诉你做的事情,即用-fPIC. 要了解此标志的作用以及在这种情况下为什么需要它,请参阅GCC 手册的代码生成选项

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

最后,您也可以在Wikipedia上阅读它。

于 2013-10-14T17:05:47.103 回答
53

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

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

基本上,这是一个变相的文件未找到错误。

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


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

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

于 2017-02-22T09:54:01.320 回答
16

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

g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...
于 2019-07-24T10:59:51.753 回答
11

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

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

于 2015-09-12T21:50:05.917 回答
4

简单地清理项目为我解决了它。

我的项目是一个 C++ 应用程序(不是共享库)。在多次成功构建后,我随机收到此错误。

于 2018-08-20T07:38:39.617 回答
2

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

于 2018-04-30T05:36:26.770 回答
0

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

我通过简单地从头开始重新安装整个东西并$ ./configure替换为的所有实例来使其工作(用于安装ffmpeg) $ ./configure --enable-shared(首先确保删除所有文件夹和文件,包括上次尝试的.so文件)。

显然这是有效的,因为https://stackoverflow.com/a/13812368/10593190

于 2020-07-04T08:07:20.537 回答
0

我们遇到了同样的问题。事实证明这是Makefile中的混淆。错误发生时链接器是gcc,但 C++ 编译器clang++。更改链接器以clang++修复它。

于 2022-02-14T16:01:18.843 回答