
关于在cmake中生成msvc项目时静态链接c / c ++运行时库的问题,我很久以前写了一个博客“ cmake设置msvc的运行时库(运行时库),并指定openjpeg使用静态当时的解决方案是在CMakeLists.txt中添加一段代码cmake 静态库,以替换/ MD替换所有变量(例如C_FLAGS_XXX,CXX_FLAGS_XXX和/ MT),从而解决了问题.
if(MSVC)
# Use the static C library for all build types
foreach(var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
if(${var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
endif()
endforeach()
endif(MSVC)
此方法确实可以解决问题,但是从工程角度来看存在一些缺陷.

1. 对于您自己的项目,如果要管理多个独立的项目,则在每个项目的CMakeLists.txt中添加一段代码非常麻烦. . . 容易犯错误.
2. 如果要编译第三方库,则还需要使用此方法,您必须修改第三方库的cmake脚本,这无疑会增加项目管理的复杂性,并且更容易出错.
我今天找到了这篇文章,它完全解决了我的问题:

msvc的默认值是使用/ MD选项. 在cmake中,此/ MD是在初始化期间设置的.
CMAKE_C_FLAGS_XXXX,CMAKE_CXX_FLAGS_XXXX和其他系列变量分别对应于初始变量后缀_INIT CMAKE_C_FLAGS_XXXX_INIT,CMAKE_CXX_FLAGS_XXXX_INIT,这些变量存储在编译选项的初始值中.
尽管本文写有一些错误,但我理解它的真实性:

基本原理是使用此cmake变量定义一个初始化脚本,通过该脚本可以修改上面提到的_INIT系列变量!!!
如下定义一个名为compile_flags_overrides.cmake的脚本. 在脚本中,将带有_INIT后缀的编译器的所有MD初始化变量更改为/ MT,
if(MSVC)
# Use the static C library for all build types
MESSAGE(STATUS "link to static C and C++ runtime lirbary(/MT /MTd)")
foreach(var
CMAKE_C_FLAGS_DEBUG_INIT
CMAKE_C_FLAGS_RELEASE_INIT
CMAKE_C_FLAGS_MINSIZEREL_INIT
CMAKE_C_FLAGS_RELWITHDEBINFO_INIT
CMAKE_CXX_FLAGS_DEBUG_INIT
CMAKE_CXX_FLAGS_RELEASE_INIT
CMAKE_CXX_FLAGS_MINSIZEREL_INIT
CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT
)
if(${var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
MESSAGE(STATUS "${var}:${${var}}")
endif()
endforeach()
endif(MSVC)

然后在调用cmake生成msvc项目时,使用CMAKE_USER_MAKE_RULES_OVERRIDE指定以前的editor_flags_overrides.cmake脚本的位置cmake 静态库,并且可以从/ MD切换到/ MT.
大致如下:
cmake .. -G "NMake Makefiles" -DCMAKE_USER_MAKE_RULES_OVERRIDE=$overrides_cmake_path
好处是显而易见的. 您可以从外部控制/ MD和/ MT选项,而无需修改原始项目的CMakeLists.txt.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-220910-1.html
人家导弹都装在发射筒里真是阿Q精神
美国人流放犯的后代