首页 文章

在CMake中设置MSVC运行时

提问于
浏览
35

我按照CMake FAQ条目"How can I build my MSVC application with a static runtime?"中的说明集中选择一组嵌套的CMake项目的MSVC运行时(它们作为Git子模块引入并使用CMake的 find_package() 指令添加到主项目中) .

所以,我写了这个CMake宏:

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 -> 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 -> 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()

我在我的根 CMakeLists.txt 的开头调用这个宏(在调用任何 add_library()add_executable() 之前)并添加一些调试打印:

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 "")

然后,我运行CMake生成一个Visual Studio解决方案,如下所示:

cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=dynamic

我得到以下输出:

-- MSVC -> 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

现在,当我启动Visual Studio并检查“C / C,代码生成”下的项目属性时,我发现“运行时库”设置与shell中打印的选项不一致 . 在“Release”,“MinSizeRel”和“RelWithDebInfo”配置下,我得到了预期的结果(“多线程DLL / MD”,但“Debug”配置仍然显示“Multi-threaded / MT”) .

此外,当我强制使用静态链接的运行时,我得到类似的结果 . 如果我跑

cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=static

我得到以下输出:

-- MSVC -> 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

然而,所有配置都为“运行时库”设置生成“多线程/ MT”值 .

我做错了什么,或者这是CMake(2.8.7)中的错误还是什么?


对于它的 Value ,如果我生成Visual Studio 2010项目文件,我会得到“调试”配置的不同值,但仍然不是我选择的那个 .

在所有情况下,设置以“Debug”配置的常规字体显示,而对于其他配置,它以粗体字体显示,暗示这些是覆盖 . 此外,如果我打开XML项目文件,我发现“Debug”配置没有为“Tool”元素的“RuntimeLibrary”属性设置“Name = VCCLCompilerTool”属性 . 所有其他配置都有明确的设置 .

2 回答

  • 5

    似乎我一直在努力解决这个问题,我忘了删除我想要替换的错误的CMake配置 .

    在构建脚本的下方,我离开了这个小bugger:

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

    基本上,我用 configure_msvc_runtime() 宏覆盖了没有设置MSVC运行时的构建标志的结果 .

  • 12

    我接受了你的代码并将其推广到每个现有配置,而不仅仅是Debug / Release / RelWithDebInfo / MinSizeRel .

    我也让它与gcc一起工作 - 检查出来here

相关问题