我想做什么
我尝试将代码分成模块,并使用-fPIC
选项将其编译为静态库。
最后,它们将使用--whole-archive
链接到共享库,该共享库也使用-fPIC
进行编译。
对于整个编译,我将CMake generated make files
和C++17
与GCC8
一起使用!
问题
尝试使用GCC8 x86_64
和libstdc++_pic
这样做会失败:
/ usr / bin / x86_64-linux-gnu-ld:CMakeFiles / shirabeengine.dir / code / source / core / engine.cpp.o:针对未定义符号'_ZN6enginelsERSoRKNS_13EEngineStatusE'的重定位R_X86_64_PC32无法使用宾语;用-fPIC重新编译 / usr / bin / x86_64-linux-gnu-ld:最终链接失败:值错误 collect2:错误:ld返回1退出状态
执行的步骤
我已完成验证,所有库均已使用-fPIC
正确构建并包含重定位信息:
ar -x <name>.a
readelf --relocs <name>.cpp.o | egrep '(GOT|PC|PLT|JU?MP_SLOT)'
来查看它是否包含重定位信息。节选:
000000000036 217600000004 R_X86_64_PLT32 0000000000000000 _ZN9__gnu_cxx17__norma-4 00000000004e 161000000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail-4 000000000019 217700000004 R_X86_64_PLT32 0000000000000000 _ZNK9__gnu_cxx17__norm-4 000000000028 217700000004 R_X86_64_PLT32 0000000000000000 _ZNK9__gnu_cxx17__norm-4 000000000044 1ff700000004 R_X86_64_PLT32 0000000000000000 _ZNSt12_Vector_baseIN6-4 00000000005e 1ff800000004 R_X86_64_PLT32 0000000000000000 _ZSt8_DestroyIPN6engin-4 000000000014 212f00000004 R_X86_64_PLT32 0000000000000000 _ZNKSt12__shared_ptrIN-4 000000000014 217800000004 R_X86_64_PLT32 0000000000000000 _ZNSt13__future_base13-4 000000000020 213100000004 R_X86_64_PLT32 0000000000000000 _ZNKSt19__shared_ptr_a-4 000000000014 212f00000004 R_X86_64_PLT32 0000000000000000 _ZNKSt12__shared_ptrIN-4 000000000025 18b300000004 R_X86_64_PLT32 0000000000000000 _ZSt20__throw_future_e-4 000000010248 089e00000002 R_X86_64_PC32 0000000000000000 .text._ZN9__gnu_cxxeqI + 0 000000010268 089f00000002 R_X86_64_PC32 0000000000000000 .text._ZNSt6vectorIN6e + 0 000000010271 007f00000002 R_X86_64_PC32 0000000000000000 .gcc_except_table + e68 00000001028c 08a000000002 R_X86_64_PC32 0000000000000000 .text._ZNKSt13packaged + 0 0000000102ac 08a100000002 R_X86_64_PC32 0000000000000000 .text。 ZNSt13已打包 + 0 0000000102cc 08a200000002 R_X86_64_PC32 0000000000000000 .text._ZN9__gnu_cxx17_ + 0 0000000102ec 08a300000002 R_X86_64_PC32 0000000000000000 .text._ZNK9__gnu_cxx17 + 0
readelf --debug-dump=macro <name>.o | grep __PIC__
来查看_PIC_
宏是否已定义并设置为2
。节选:
DW_MACRO_define_strp-lineno:0宏: PIC 2
结果
所有测试均验证了静态库和共享库的每个目标文件的-fPIC
编译和重定位符号存储成功。
唯一无效的东西:
如链接器错误所报告,在命名空间enum class EEngineStatus
中包含engine
。符号_ZN6enginelsERSoRKNS_13EEngineStatusE
不包含在受影响的engine.cpp.o
中。
怀疑的影响力
我将其中一个静态库与vulkan SDK链接,据我所知,该库尚未-fPIC
编译。
这会中断与vulkan SDK无关的库的整个链接吗?
帮助
有人知道我在做什么吗?
我衷心希望,任何人都可以提供帮助。 我的知识显然还很有限。
提前谢谢您。
在@jww写下答案之前,我将在此处提供该答案供其他人使用。
事实证明标题已处理,但我不理解该消息。
由于@jww,我学会了如何对未定义的符号进行解贴:
echo _ZN6enginelsERSoRKNS_13EEngineStatusE | c ++ filt
这产生了未实现的功能,因此丢失了,我能够解决问题。