Использование опции компоновщика --whole-archive с CMake и библиотеками с другими зависимостями библиотеки - PullRequest
0 голосов
/ 30 октября 2018

У меня есть проект, который раньше представлял собой гигантский набор исходных файлов, которые были скомпилированы и затем связаны как один исполняемый файл. В качестве первого шага, чтобы сделать проект более модульным, я разбил сборку на несколько более мелких частей и сделал их статическими библиотеками. Существует иерархия, поэтому Exe1 будет связывать статические библиотеки Lib2A и Lib2B. Lib2A будет зависеть от статического Lib3A, lib3B, lib3C и т. Д. Числа здесь показывают их слой в иерархии.

Проблема в том, что мне нужно использовать --whole-archive при компоновке, иначе некоторые символы из базовых библиотек не найдены.

Когда я добавляю ниже для связывания Exe1:

target_link_libraries(Exe1 -Wl,--whole-archive Lib2A Lib2B -Wl,--no-whole-archive)

В результате я получаю команду этапа реальной ссылки, например:

g++ -o Exe1 -Wl,--whole-archive libLib2A.a libLib2B.a -Wl,--no-whole-archive libLib3A.a libLib3B.a libLib3C.a

Неизбежно, символы из некоторых статических библиотек уровня 3 теряются, и я пропускаю ошибки символов.

Я ожидал, что поскольку Lib2A имеет библиотеки Lib3 * в качестве зависимостей, они также будут "внутри" части --whole-archive команды компоновщика, но они отображаются снаружи.

Я пробовал много разных комбинаций (например, поместил материал --whole-archive на нижние уровни), но не сталкивался с подходом, который работает с использованием CMake. Что я делаю не так?

Спасибо

1 Ответ

0 голосов
/ 02 ноября 2018

Для 3.12 и более новых версий CMake я бы использовал библиотеки объектов.

Обходной путь, который я нашел для более ранних версий, заключался в создании промежуточной статической библиотеки, которая использовала магию свойств для размещения всех зависимостей связей внутри раздела --whole-archive. Для меня статическая библиотека верхнего уровня называлась «источник». На самом деле он сам ничего не содержал, но имел зависимости от связки с кучей других статических библиотек. Я создал «источник-комбинированный» следующим образом:

add_library(source-combined STATIC "")
set_target_properties(source-combined PROPERTIES LINKER_LANGUAGE CXX)

target_link_libraries(source-combined PUBLIC
  --Wl,--whole-archive
  $<TARGET_PROPERTY:source,INTERFACE_LINK_LIBRARIES>
  -Wl,--no-whole-archive
)

Теперь, когда я создаю исполняемый файл или разделяемую библиотеку, связываясь с этой объединенной библиотекой souce, я получаю --whole-archive и --no-whole-archive в качестве форзацев для набора весь статических библиотек, которые были ссылочными зависимостями «источника». Мне пришлось столкнуться с этой техникой навсегда, поэтому я делюсь ею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...