【发布时间】:2018-10-29 18:35:29
【问题描述】:
我尝试使用 cmake + ninja + msvc 在 Windows 上构建一个相当大的共享库,它由来自子文件夹的多个静态库组成。所以根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")
子文件夹 staticlib1 和 staticlib2 中的 CMakeLists.txt 看起来都类似于:
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 遵循相同的模式。
【问题讨论】: