Note that there are some explanatory texts on larger screens.

plurals
  1. POSetting the MSVC runtime in CMake
    primarykey
    data
    text
    <p>I'm following the instructions in the CMake FAQ entry <a href="http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F" rel="noreferrer">"How can I build my MSVC application with a static runtime?"</a> to centralize selection of the MSVC runtime for a bunch of nested CMake projects (they are pulled in as Git submodules and added to the master project using CMake's <code>find_package()</code> directive).</p> <p>So, I wrote this CMake macro:</p> <pre><code>macro(configure_msvc_runtime) if(MSVC) # Default to statically-linked runtime. if("${MSVC_RUNTIME}" STREQUAL "") set(MSVC_RUNTIME "static") endif() # Set compiler options. set(variables CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO ) if(${MSVC_RUNTIME} STREQUAL "static") message(STATUS "MSVC -&gt; forcing use of statically-linked runtime." ) foreach(variable ${variables}) if(${variable} MATCHES "/MD") string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}") endif() endforeach() else() message(STATUS "MSVC -&gt; forcing use of dynamically-linked runtime." ) foreach(variable ${variables}) if(${variable} MATCHES "/MT") string(REGEX REPLACE "/MT" "/MD" ${variable} "${${variable}}") endif() endforeach() endif() endif() endmacro() </code></pre> <p>I call this macro at the beginning of my root <code>CMakeLists.txt</code> (before <em>any</em> <code>add_library()</code> or <code>add_executable()</code> call is made) and add a little bit of debugging prints:</p> <pre><code>configure_msvc_runtime() set(variables CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO ) message(STATUS "Initial build flags:") foreach(variable ${variables}) message(STATUS " '${variable}': ${${variable}}") endforeach() message(STATUS "") </code></pre> <p>Then, I run CMake to generate a Visual Studio solution like so:</p> <pre><code>cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=dynamic </code></pre> <p>and I get the following outputs:</p> <pre><code>-- MSVC -&gt; forcing use of dynamically-linked runtime. -- Initial build flags: -- 'CMAKE_C_FLAGS_DEBUG': /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 -- 'CMAKE_C_FLAGS_MINSIZEREL': /MD /O1 /Ob1 /D NDEBUG -- 'CMAKE_C_FLAGS_RELEASE': /MD /O2 /Ob2 /D NDEBUG -- 'CMAKE_C_FLAGS_RELWITHDEBINFO': /MD /Zi /O2 /Ob1 /D NDEBUG -- 'CMAKE_CXX_FLAGS_DEBUG': /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 -- 'CMAKE_CXX_FLAGS_MINSIZEREL': /MD /O1 /Ob1 /D NDEBUG -- 'CMAKE_CXX_FLAGS_RELEASE': /MD /O2 /Ob2 /D NDEBUG -- 'CMAKE_CXX_FLAGS_RELWITHDEBINFO': /MD /Zi /O2 /Ob1 /D NDEBUG </code></pre> <p>Now, the thing is that when I start Visual Studio and examine the project properties under "C/C++, Code Generation", I see that the "Runtime Library" setting is not consistent with the options printed in the shell. Under the "Release", "MinSizeRel" and "RelWithDebInfo" configurations, I get the expected results ("Multi-threaded DLL /MD", but the "Debug" configuration still displays "Multi-threaded /MT".</p> <p>Also, when I force use of the statically-linked runtime, I get similar results. If I run</p> <pre><code>cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=static </code></pre> <p>I get the following outputs:</p> <pre><code>-- MSVC -&gt; forcing use of statically-linked runtime. -- Initial build flags: -- 'CMAKE_C_FLAGS_DEBUG': /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1 -- 'CMAKE_C_FLAGS_MINSIZEREL': /MT /O1 /Ob1 /D NDEBUG -- 'CMAKE_C_FLAGS_RELEASE': /MT /O2 /Ob2 /D NDEBUG -- 'CMAKE_C_FLAGS_RELWITHDEBINFO': /MT /Zi /O2 /Ob1 /D NDEBUG -- 'CMAKE_CXX_FLAGS_DEBUG': /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1 -- 'CMAKE_CXX_FLAGS_MINSIZEREL': /MT /O1 /Ob1 /D NDEBUG -- 'CMAKE_CXX_FLAGS_RELEASE': /MT /O2 /Ob2 /D NDEBUG -- 'CMAKE_CXX_FLAGS_RELWITHDEBINFO': /MT /Zi /O2 /Ob1 /D NDEBUG </code></pre> <p>And yet all configurations produce the "Multi-threaded /MT" value for the "Runtime Library" setting.</p> <p>Can someone tell me what I'm doing wrong, or if this is a bug in CMake (2.8.7) or something ?</p> <hr> <p>For what it's worth, If I generate Visual Studio 2010 project files, I get a different value for the "Debug" configuration, but still not the one I selected. In all cases, the setting appears in regular font for the "Debug" configuration whereas it appears in bolded font for the other configurations, hinting that those are overrides. Moreover, if I open the XML project files, I find that the "Debug" configuration has no setting for the "RuntimeLibrary" attribute of the "Tool" element with the "Name=VCCLCompilerTool" attribute. All other configurations have an explicit setting.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload