Я пытался создать довольно большую разделяемую библиотеку в 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 следовал той же схеме.