Setting the MSVC runtime in CMake

I took your code and generalized it to work for every existing configuration and not just for Debug/Release/RelWithDebInfo/MinSizeRel.

Also I made it to work with gcc too - check it out here


This functionality will be improved with the release of cmake-3.15.

  • CMAKE_MSVC_RUNTIME_LIBRARY
  • CMP0091

It should be a matter of setting CMAKE_MSVC_RUNTIME_LIBRARY, for example (from docs) to set "multi-threaded statically-linked runtime library with or without debug information depending on the configuration":

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

It seems all the while I was working on this, I forgot to remove the bad CMake configuration I'm trying to replace.

Further down the build script, I had left this little bugger:

set(CMAKE_CXX_FLAGS_DEBUG
  "/DWIN32 /D_WINDOWS /EHsc /WX /wd4355 /wd4251 /wd4250 /wd4996"
  CACHE STRING "Debug compiler flags" FORCE
)

Basically, I was overriding the results of by configure_msvc_runtime() macro with build flags that did not set the MSVC runtime.


Here is a solution that I came up with, which should work for CMake versions before and after 3.15.

# This logic needs to be considered before project()
set(_change_MSVC_flags FALSE)
if(WIN32)
  if(CMAKE_VERSION VERSION_LESS 3.15.0)
    set(_change_MSVC_flags TRUE)
  else()
    # Set MSVC runtime to MultiThreaded (/MT)
    cmake_policy(SET CMP0091 NEW)
    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
  endif()
endif()

project(MyProj ....)

if(_change_MSVC_flags)
  # Modify compile flags to change MSVC runtime from /MD to /MT
  set(_re_match "([\\/\\-]M)D")
  set(_re_replace "\\1T")
  string(REGEX REPLACE ${_re_match} ${_re_replace}
    CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  string(REGEX REPLACE ${_re_match} ${_re_replace}
    CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
  string(REGEX REPLACE ${_re_match} ${_re_replace}
    CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
  string(REGEX REPLACE ${_re_match} ${_re_replace}
    CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
  string(REGEX REPLACE ${_re_match} ${_re_replace}
    CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
endif()

If other languages are used (i.e. C), then these would also need to be added too.