Linking static libraries into shared: enum class in header -> relocation R_X86_64_PC32 against undefined symbol

北战南征 提交于 2021-02-10 05:19:50

问题


What I want to do

I try to separate my code into modules, which are compiled as static libraries with the -fPIC option.

Finally, they are to be linked into a shared library using --whole-archive, also compiled with -fPIC.

For the whole compilation, I use CMake generated make files and C++17 with GCC8!

Problem

Trying to do so with GCC8 x86_64 and libstdc++_pic fails with:

/usr/bin/x86_64-linux-gnu-ld: CMakeFiles/shirabeengine.dir/code/source/core/engine.cpp.o: relocation R_X86_64_PC32 against undefined symbol `_ZN6enginelsERSoRKNS_13EEngineStatusE' can not be used when making a shared object; recompile with -fPIC /usr/bin/x86_64-linux-gnu-ld: final link failed: Bad value collect2: error: ld returned 1 exit status


Performed steps

Things I've done to verify, that all libraries are properly built with -fPIC and contain relocation info:

  1. I unpacked all static libraries ar -x <name>.a
  2. I ran readelf --relocs <name>.cpp.o | egrep '(GOT|PC|PLT|JU?MP_SLOT)' on each object-file to see if it contains relocation information.

Excerpt:

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.ZNSt13packaged + 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

  1. I ran readelf --debug-dump=macro <name>.o | grep __PIC__ to see, whether the _PIC_ macro was defined and set to 2, as described by the gcc compiler option reference.

Excerpt:

DW_MACRO_define_strp - lineno : 0 macro : PIC 2

  1. I crawled more 50 articles, stackoverflow entries and answers, all related to unresolved symbols related to functions/methods defined in the .cpp-files. In my case it's a symbol defined in a header-file, which is not found, which is why I created another question.

Result

All tests verified successful -fPIC compilation and relocation symbol storage for each object file of the static libraries and shared libraries.

The only thing that didn't work: The inclusion of the enum class EEngineStatus in the namespace engine, as reported by the linker error. The symbol _ZN6enginelsERSoRKNS_13EEngineStatusE is not contained in the affected engine.cpp.o.


Suspected Influence

I link one of the static libraries against the vulkan SDK, which is not -fPIC compiled as far as I know.

Could this break the entire linkage of a library unrelated to the vulkan SDK?


Help

Does anyone know, what I do wrong?

I sincerely hope, that anyone can help. My knowledge is obviously too limited yet.

THank you in advance.

Solution

Until @jww will write his answer, I'll provide it here for others to find.

It turns out that the header was processed, but I didn't understand the message.

Thanks to @jww I learned how to demangle the undefined symbol:

echo _ZN6enginelsERSoRKNS_13EEngineStatusE | c++filt

This yielded the function not implemented, thus missing and I was able to fix the issues.

来源:https://stackoverflow.com/questions/52234570/linking-static-libraries-into-shared-enum-class-in-header-relocation-r-x86-6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!