在 CMake 中设置 MSVC 运行时 [英] Setting the MSVC runtime in CMake
问题描述
我正在遵循 CMake 常见问题条目中的说明 "我如何构建我的 MSVC具有静态运行时的应用程序?" 为一堆嵌套的 CMake 项目集中选择 MSVC 运行时(它们作为 Git 子模块引入并使用 CMake 的 find_package()
指令).
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).
所以,我写了这个 CMake 宏:
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()
我在我的根 CMakeLists.txt
的开头调用这个宏(在 any add_library()
或 add_executable() 之前)
调用)并添加一点调试打印:
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 "")
然后,我运行 CMake 来生成一个 Visual Studio 解决方案,如下所示:
Then, I run CMake to generate a Visual Studio solution like so:
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"配置下,我得到了预期的结果(Multi-threaded DLL/MD",但Debug"配置仍然显示Multi-threaded/MT").
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
我得到以下输出:
-- 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"值.
And yet all configurations produce the "Multi-threaded /MT" value for the "Runtime Library" setting.
我做错了什么,或者这是 CMake (2.8.7) 中的错误还是什么?
What am I doing wrong, or if this is a bug in CMake (2.8.7) or something?
就其价值而言,如果我生成 Visual Studio 2010 项目文件,我会得到不同的调试"配置值,但仍然不是我选择的值.
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.
在所有情况下,调试"配置的设置以常规字体显示,而其他配置以粗体显示,暗示这些是覆盖.此外,如果我打开 XML 项目文件,我发现调试"配置没有设置工具"元素的RuntimeLibrary"属性和Name=VCCLCompilerTool"属性.所有其他配置都有明确的设置.
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.
推荐答案
似乎在我处理这个问题的过程中,我忘记删除我试图替换的错误的 CMake 配置.
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
)
基本上,我使用未设置 MSVC 运行时的构建标志覆盖了 configure_msvc_runtime()
宏的结果.
Basically, I was overriding the results of by configure_msvc_runtime()
macro with build flags that did not set the MSVC runtime.
这篇关于在 CMake 中设置 MSVC 运行时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!