остановите cmake target_link_libraries, связывающий оба объектных файла статической библиотеки в дополнение к самой статической библиотеке - PullRequest
0 голосов
/ 29 октября 2018

Я пытался создать довольно большую разделяемую библиотеку в Windows с помощью cmake + ninja + msvc, которая состоит из нескольких статических библиотек из подпапок. Итак, корень CMakeLists.txt выглядит так:

project (sharedlib CXX)
include(${CMAKE_CURRENT_LIST_DIR}/staticlib1/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/staticlib2/CMakeLists.txt)

add_library(sharedlib SHARED)

target_link_libraries(sharedlib
    staticlib1
    staticlib2
)

set_target_properties(wux PROPERTIES LINK_FLAGS "/WHOLEARCHIVE")

Где CMakeLists.txt в подпапках staticlib1 и staticlib2 выглядят примерно так:

add_library(staticlib1 STATIC)
target_sources(staticlib1 PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}/sourceA.cpp
    ${CMAKE_CURRENT_LIST_DIR}/sourceB.cpp
)

target_include_directories(staticlib1 PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}/inc
)

target_compile_options(staticlib1 PUBLIC
    /flag1
    /flag2
)

Когда я запускаю cmake --build, и staticlib1, и staticlib2 создаются без проблем. Здорово. Но когда компоновщик пытается собрать sharedlib, сгенерированный cmake rsp-файл имеет:

CMakeFiles\sharedlib.dir\staticlib1\sourceA.cpp.obj
CMakeFiles\sharedlib.dir\staticlib1\sourceB.cpp.obj
CMakeFiles\sharedlib.dir\staticlib2\sourceC.cpp.obj
CMakeFiles\sharedlib.dir\staticlib2\sourceD.cpp.obj
staticlib1.lib
staticlib2.lib

Итак, я получаю ошибки компоновщика, потому что символы определены дважды. Как мне заставить cmake перестать добавлять объекты и конечные библиотеки в компоновщик rsp?

Технически, мне не нужны статичные библиотеки после свершившегося факта. Однако я не могу просто переключиться на использование библиотек OBJECT. Фактический проект имеет ~ 250 статических библиотек, включая ~ 3500 объектных файлов. Линкер умирает (не хватает памяти) только с небольшой частью объектных файлов.

Сначала я должен собрать статические библиотеки, а затем связать их в общую библиотеку, чтобы обойти ограничения компоновщика. Наши текущие сценарии сборки точно следуют этому шаблону, поэтому я знаю, что он работает. Мне просто нужно, чтобы cmake следовал той же схеме.

1 Ответ

0 голосов
/ 29 октября 2018

Это эффект команды target_sources : с ключевым словом PUBLIC он добавляет источники как для библиотеки (статической), так и для всех, кто связывает эту библиотеку.

Вместо этого следует использовать ключевое слово PRIVATE или, что лучше, добавить источники в сам вызов add_library:

add_library(staticlib1 STATIC
    ${CMAKE_CURRENT_LIST_DIR}/sourceA.cpp
    ${CMAKE_CURRENT_LIST_DIR}/sourceB.cpp
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...