赞
踩
关于在cmake生成msvc工程时静态链接c/c++运行库的问题,很久以前写过一篇博客《cmake设置msvc的运行库(runtime library)塈指定openjpeg使用静态库》。当时的办法是在CMakeLists.txt中加一段代码将C_FLAGS_XXX,CXX_FLAGS_XXX等所有变量中的/MD
替换成/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脚本,无疑就增加了工程管理的复杂度,更容易出错。
今天找到这篇文章《How can I build my MSVC application with a static runtime?》,才完全解决了我的问题:
msvc默认就是使用/MD选项,在cmake中,这个/MD是在初始化时就被设置的。
CMAKE_C_FLAGS_XXXX,CMAKE_CXX_FLAGS_XXXX等系列变量每一个都对应一个后缀为_INIT的初始变量CMAKE_C_FLAGS_XXXX_INIT,CMAKE_CXX_FLAGS_XXXX_INIT,这些变量中保存的就是编译选项的初始值。
这篇文章虽然写的有些错误,但我明白了它的道理:
基本的原理就是利用CMAKE_USER_MAKE_RULES_OVERRIDE这个cmake变量,定义一个初始化脚本,通过这个初始化脚本可以修改上面所说的_INIT系列变量!!!
如下定义一个名为 compiler_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
指定前面compiler_flags_overrides.cmake脚本的位置,就可以实现/MD
到/MT
的切换了。
大致如下:
cmake .. -G "NMake Makefiles" -DCMAKE_USER_MAKE_RULES_OVERRIDE=$overrides_cmake_path
这样的好处显而易见,不需要修改原项目的CMakeLists.txt,在外部就能控制/MD
和/MT
选项。
#参考资料:
《How can I build my MSVC application with a static runtime?》
《CMAKE_USER_MAKE_RULES_OVERRIDE》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。