在CMake中设置MSVC运行时 [英] Setting the MSVC runtime in CMake

查看:728
本文介绍了在CMake中设置MSVC运行时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照CMake常见问题解答中的说明如何使用静态运行时构建我的MSVC应用程序?集中选择一个嵌套的CMake项目的MSVC运行时(它们被作为Git子模块引入,并使用CMake的 find_package()

因此,我写了这个CMake宏:

 宏(configure_msvc_runtime)
if(MSVC)
#默认为静态链接运行时。
if($ {MSVC_RUNTIME}STREQUAL)
set(MSVC_RUNTIMEstatic)
endif()
#设置编译器选项。
组(变量
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} STREQUALstatic)
消息(STATUS
MSVC->强制使用静态链接的运行时。

$ foreach($ {variables})
if($ {variable} MATCHES/ MD)
string(REGEX REPLACE/ MD/ MT$ {variable}$ {$ {变量}})
endif()
endforeach()
else()
message(STATUS
MSVC - >强制使用动态链接的运行时。 $ MT/ MD)
字符串(REGEX REPLACE/ MTMD)


$ b $ {variable}$ {$ {variable}})
endif()
endforeach()
endif()
endif b $ b

我在我的根开头调用此宏 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

消息(状态初始构建标记:)
foreach()
endforeach()
($ {然后,我运行CMake生成一个Visual Studio解决方案,如下所示:

/ p>

  cmake -GVisual Studio 9 2008.. \ .. -DMSVC_RUNTIME = dynamic 

,我得到以下输出:

 <$ c $ > MSVC->强制使用动态链接的运行时。 
- 初始构建标志:
- '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 -GVisual Studio 9 2008.. \ .. -DMSVC_RUNTIME = static 


$ b b

我得到以下输出:

   -  MSVC  - 强制使用静态链接的运行时
- 初始构建标志:
- '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)或某事中的错误?






对于值得的,如果我生成Visual Studio 2010项目文件,我得到一个不同的值为调试配置,但仍然不是我选择的一个。在所有情况下,设置对于调试配置以正常字体显示,而对于其他配置以粗体字体显示,暗示这些是覆盖。此外,如果我打开XML项目文件,我发现Debug配置没有为工具元素的RuntimeLibrary属性设置Name = VCCLCompilerTool属性。所有其他配置都有明确的设置。

解决方案

似乎所有的工作, CMake配置我要替换。



进一步下了构建脚本,我离开了这个小bug:

  set(CMAKE_CXX_FLAGS_DEBUG 
/ DWIN32 / D_WINDOWS / EHsc / WX / wd4355 / wd4251 / wd4250 / wd4996
CACHE STRING调试编译器标志FORCE

基本上,我覆盖了 configure_msvc_runtime



抱歉的麻烦!


I'm following the instructions in the CMake FAQ entry "How can I build my MSVC application with a static runtime?" 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 find_package() directive).

So, I wrote this CMake macro:

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

I call this macro at the beginning of my root CMakeLists.txt (before any add_library() or add_executable() call is made) and add a little bit of debugging prints:

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

Then, I run CMake to generate a Visual Studio solution like so:

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

and I get the following outputs:

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

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

Also, when I force use of the statically-linked runtime, I get similar results. If I run

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

I get the following outputs:

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

And yet all configurations produce the "Multi-threaded /MT" value for the "Runtime Library" setting.

Can someone tell me what I'm doing wrong, or if this is a bug in CMake (2.8.7) or something ?


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.

解决方案

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.

Sorry for the trouble!

这篇关于在CMake中设置MSVC运行时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆