Я пытался выяснить это в течение нескольких дней, основываясь на различных существующих SO и архивах списков рассылки cmake. Однако я не могу понять, как это сделать.
Я хочу создать библиотеку с именем libA
, которая будет общей библиотекой, которая будет использоваться другим исполняемым файлом. libA
имеет много внутренних зависимостей (libB
, libC
, libD
, ...), которые создаются / представляются либо как stati c библиотеки, либо как библиотеки объектов cmake. libA
должен содержать весь код, чтобы быть самосогласованной разделяемой библиотекой, с которой приложение может ссылаться без необходимости распространения внутренних зависимостей.
libA
строится так:
add_library(libA-objs OBJECT ${HEADERS_PUBLIC} ${HEADERS_PRIVATE} ${SOURCES_PRIVATE})
target_compile_options(libA-objs
PRIVATE
-o1
-Wall -Wextra -pedantic
-Wl,--whole-archive
)
target_link_libraries(libA-objs
PRIVATE
libB
libC
libD
)
...
# Build static library
add_library(libA-static STATIC)
target_link_libraries(libA-static PUBLIC libA-objs)
# Build shared library
add_library(libA-shared SHARED)
target_link_libraries(libA-shared PUBLIC libA-objs)
Я правильно устанавливаю libA
в системе. У меня также есть все, что нужно для экспорта libA
таким образом, чтобы приложение-потребитель могло просто использовать find_package()
.
Приложение, потребляющее libA-shared
, само является разделяемой библиотекой (плагин для стороннего приложения). ):
find_package(libA REQUIRED)
add_library(myplugin SHARED)
target_link_libraries(myplugin
PRIVATE
libA::libA-shared
)
При попытке сборки компоновщик жалуется на невозможность найти / разрешить / связать libB
, libC
и libD
. Я проверил файл конфигурации целей, сгенерированный cmake при установке экспортированных целей (сценариев, которые приложение-потребитель использует через find_package()
), и вижу, что libA-shared
содержит ссылки на libB
, libC
и libD
в INTERFACE_LINK_LIBRARIES
как LINK_ONLY
.
Учитывая, что libA-objs
ссылается на внутренние зависимости как PRIVATE
и учитывая, что я создаю разделяемую библиотеку (исполняемый файл!) вместе с включением целых архивов зависимостей I предположил бы, что это просто работать. Я не понимаю, почему внутренние зависимости отображаются в командах связывания потребляющего исполняемого файла, поскольку они помечены как PRIVATE
в пределах цели libA-objs
.
Как мне решить эту проблему?
Я использую CMake 3.15, G CC 9.2 и хотел бы, чтобы это также работало с clang 8.0.