How to enable MSVC static runtime linking with CMake

In the process of converting a Projucer-base build to a CMake based build I wonder what’s the right way to enable MSVC static runtime linkage for Windows builds?

The simplest way is to use CMake 3.15 or higher (you should set cmake_minimum_required(VERSION 3.15)), and to use the MSVC_RUNTIME_LIBRARY property, or the CMAKE_MSVC_RUNTIME_LIBRARY variable.

1 Like

I’m trying to do this in a project that has a new dependency on a library that requires static linking with the MSVC runtime.

In my top-level CMakeLists.txt I have:

if (MSVC)
    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MT")
endif ()

I’m getting errors like this:

libcpmtd.lib(xlocale.obj) : error LNK2005: "public: unsigned short const * __cdecl std::_Locinfo::_W_Getmonths(void)const " (?_W_Getmonths@_Locinfo@std@@QEBAPEBGXZ) already defined in msvcprtd.lib(MSVCP140D.dll)
libcpmtd.lib(xmtx.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in juce_audio_plugin_client_Standalone.cpp.obj

I also tried setting for individual targets e.g.:

if(MSVC)
    set_property(TARGET ${PROJECT_NAME} PROPERTY
            MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()

Anything I’ve missed?

I suspect the problem is that you are setting CMAKE_MSVC_RUNTIME_LIBRARY and also adding /MT to your cxx flags. I’d recommend removing this extra cxx flag. You may need to remove your build directory and reconfigure in order for the new cxx flags to take effect.

1 Like

I added the MT flag as an extra measure. It didn’t seem to make any difference. I’ll report back in any case

I do this:

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

I think it need to be a cache variable to ‘stick’.
Also no need to check for MSVC there as this setting works for CLANG too.

You can just wrap it in:

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
    #doWindowsStuff()
endif()
1 Like