我正在按照 CMake 常见问题解答条目“如何使用静态运行时构建我的 MSVC 应用程序?”中的说明进行操作。为一堆嵌套的 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()
oradd_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”配置下,我得到了预期的结果(“Multi-threaded 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) 中的错误还是什么?
对于它的价值,如果我生成 Visual Studio 2010 项目文件,我会为“调试”配置获得不同的值,但仍然不是我选择的那个。
在所有情况下,“调试”配置的设置以常规字体显示,而其他配置以粗体显示,暗示这些是覆盖。此外,如果我打开 XML 项目文件,我发现“Debug”配置没有设置“Tool”元素的“RuntimeLibrary”属性,“Name=VCCLCompilerTool”属性。所有其他配置都有明确的设置。