关于 -fPIC 的链接错误,即使所有源代码都是使用 -fPIC 编译的

Linking errors regarding -fPIC even though all sources are compiled with -fPIC

我在 Google 上找不到直接的答案,而且由于我很长时间没有在 Linux 上做任何事情,希望能在这里找到帮助。构建共享对象时,我在 Ubuntu 上收到链接错误。链接器告诉我应该使用 -fPIC 重新编译,即使我已经为所有源文件设置了 -fPICmake的输出:

mkdir -p ../_Bin/Debug/HttpClientApi
g++ -fPIC -pedantic -Wall -Wextra -std=c++11 -c CentralServerClient.cpp -o ../_Bin/Debug/HttpClientApi/CentralServerClient.o
CentralServerClient.cpp:4:80: warning: unused parameter ‘pEventListener’ [-Wunused-parameter]
 void CCentralServerClient::AddEventListener(ICentralServerClientEventListener* pEventListener)
                                                                            ^
CentralServerClient.cpp:29:83: warning: unused parameter ‘pEventListener’ [-Wunused-parameter]
 void CCentralServerClient::RemoveEventListener(ICentralServerClientEventListener* pEventListener)
                                                                               ^
g++ -fPIC -pedantic -Wall -Wextra -std=c++11 -c HttpRequest.cpp -o ../_Bin/Debug/HttpClientApi/HttpRequest.o
g++ -fPIC -pedantic -Wall -Wextra -std=c++11 -c HttpResponse.cpp -o ../_Bin/Debug/HttpClientApi/HttpResponse.o
g++ -fPIC -pedantic -Wall -Wextra -std=c++11 -c IOService.cpp -o ../_Bin/Debug/HttpClientApi/IOService.o
g++ -Wl,-shared -Wl,-v -Wl,-g -o ../_Bin/Debug/HttpClientApi.so ../_Bin/Debug/HttpClientApi/CentralServerClient.o ../_Bin/Debug/HttpClientApi/HttpRequest.o ../_Bin/Debug/HttpClientApi/HttpResponse.o ../_Bin/Debug/HttpClientApi/IOService.o
collect2 version 4.9.2
/usr/bin/ld -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccZ9RMHe.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o ../_Bin/Debug/HttpClientApi.so /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.9 -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. -shared -v -g ../_Bin/Debug/HttpClientApi/CentralServerClient.o ../_Bin/Debug/HttpClientApi/HttpRequest.o ../_Bin/Debug/HttpClientApi/HttpResponse.o ../_Bin/Debug/HttpClientApi/IOService.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o
GNU ld (GNU Binutils for Ubuntu) 2.25
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o: relocation R_X86_64_32S against `__libc_csu_fini' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:15: recipe for target '../_Bin/Debug/HttpClientApi.so' failed
make: *** [../_Bin/Debug/HttpClientApi.so] Error 1

gcc 是 gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13)

感谢任何帮助。

你应该给它 -shared 而不是 g++ -Wl,-shared。原因是 g++ 需要知道使用哪个 crt1.o - 一个适合共享库(用 -fPIC、scrt1.o 编译)或一个不适合。

当你将 -shared 给 g++ 时,它知道使用 scrt1.o。但是当你传递 `-Wl,-shared' 时,g++ 不知道你正在构建共享库 - 它 'thinks',你正在构建一个普通的可执行文件(linker 确实知道发生了什么)并要求 linker 与 crt1.o 一起 link。链接器拒绝,你有一个错误。