Что я хочу сделать
Я пытаюсь разделить мой код на модули, которые скомпилированы как статические библиотеки с опцией -fPIC
.
Наконец, они должны быть связаны с общей библиотекой, используя --whole-archive
, также скомпилированной с -fPIC
.
Для всей компиляции я использую CMake generated make files
и C++17
с GCC8
!
![enter image description here](https://i.stack.imgur.com/MsrUQ.png)
Задача
Попытка сделать это с GCC8 x86_64
и libstdc++_pic
завершается неудачно с:
/ usr / bin / x86_64-linux-gnu-ld: CMakeFiles / shirabeengine.dir / code / source / core / engine.cpp.o: перемещение R_X86_64_PC32 против неопределенного символа `_ZN6enginelsERSoRKNS_13EEngineStatusE 'не может использоваться, когда разделяемое использование невозможно объект; перекомпилировать с -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
, как описано в справочнике по опциям компилятора gcc.
Выдержка:
DW_MACRO_define_strp - белье: 0 макрос: PIC 2
- Я просмотрел более 50 статей, записей и ответов на стеке, все они связаны с неразрешенными символами, связанными с функциями / методами, определенными в .cpp-файлах. В моем случае это символ, определенный в заголовочном файле, который не найден, который
Вот почему я создал еще один вопрос.
Результат
Все тесты подтверждены успешно -fPIC
Хранение символов компиляции и перемещения для каждого объектного файла статических и общих библиотек.
Единственное, что не сработало:
Включение enum class EEngineStatus
в пространство имен engine
, о котором сообщает ошибка компоновщика. Символ _ZN6enginelsERSoRKNS_13EEngineStatusE
не содержится в затронутом engine.cpp.o
.
Предполагаемое влияние
Я связываю одну из статических библиотек с vulkan SDK, который, насколько я знаю, не -fPIC
скомпилирован.
Может ли это нарушить всю связь библиотеки, не связанной с vulkan SDK?
Помощь
Кто-нибудь знает, что я делаю не так?
Я искренне надеюсь, что любой может помочь.
Мои знания явно слишком ограничены.
Заранее спасибо.
Решение
Пока @jww не напишет свой ответ, я предоставлю его здесь, чтобы другие могли его найти.
Оказывается, заголовок обработан, но я не понял сообщение.
Благодаря @jww я узнал, как разобрать неопределенный символ:
echo _ZN6enginelsERSoRKNS_13EEngineStatusE | C ++ ФИЛТР
Это привело к тому, что функция не была реализована, поэтому отсутствовала, и я смог исправить проблемы.