And*_*ron 38 cmake visual-studio
我按照CMake FAQ条目"如何使用静态运行时构建我的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()
Run Code Online (Sandbox Code Playgroud)
我在我的root的开头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 "")
Run Code Online (Sandbox Code Playgroud)
然后,我运行CMake生成一个Visual Studio解决方案,如下所示:
cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=dynamic
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
-- 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
Run Code Online (Sandbox Code Playgroud)
现在,当我启动Visual Studio并检查"C/C++,代码生成"下的项目属性时,我发现"运行时库"设置与shell中打印的选项不一致.在"Release","MinSizeRel"和"RelWithDebInfo"配置下,我得到了预期的结果("多线程DLL/MD",但"Debug"配置仍然显示"Multi-threaded/MT").
此外,当我强制使用静态链接的运行时,我得到类似的结果.如果我跑
cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=static
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
-- 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
Run Code Online (Sandbox Code Playgroud)
然而,所有配置都为"运行时库"设置生成"多线程/ MT"值.
我做错了什么,或者这是CMake(2.8.7)中的错误还是什么?
对于它的价值,如果我生成Visual Studio 2010项目文件,我会得到"调试"配置的不同值,但仍然不是我选择的那个.
在所有情况下,设置以"Debug"配置的常规字体显示,而对于其他配置,它以粗体字体显示,暗示这些是覆盖.此外,如果我打开XML项目文件,我发现"Debug"配置没有为"Tool"元素的"RuntimeLibrary"属性设置"Name = VCCLCompilerTool"属性.所有其他配置都有明确的设置.
And*_*ron 12
似乎我一直在努力解决这个问题,我忘了删除我想要替换的错误的CMake配置.
在构建脚本的下方,我离开了这个小bugger:
set(CMAKE_CXX_FLAGS_DEBUG
"/DWIN32 /D_WINDOWS /EHsc /WX /wd4355 /wd4251 /wd4250 /wd4996"
CACHE STRING "Debug compiler flags" FORCE
)
Run Code Online (Sandbox Code Playgroud)
基本上,我configure_msvc_runtime()使用没有设置MSVC运行时的构建标志来覆盖宏的结果.
Har*_*lon 10
随着 cmake-3.15 的发布,此功能将得到改进。
这应该是一个设置问题CMAKE_MSVC_RUNTIME_LIBRARY,例如(来自文档)设置“多线程静态链接运行时库,根据配置有或没有调试信息”:
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
Run Code Online (Sandbox Code Playgroud)
这是我提出的一个解决方案,它应该适用于 3.15 之前和之后的 CMake 版本。
# This logic needs to be considered before project()
set(_change_MSVC_flags FALSE)
if(WIN32)
if(CMAKE_VERSION VERSION_LESS 3.15.0)
set(_change_MSVC_flags TRUE)
else()
# Set MSVC runtime to MultiThreaded (/MT)
cmake_policy(SET CMP0091 NEW)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
endif()
project(MyProj ....)
if(_change_MSVC_flags)
# Modify compile flags to change MSVC runtime from /MD to /MT
set(_re_match "([\\/\\-]M)D")
set(_re_replace "\\1T")
string(REGEX REPLACE ${_re_match} ${_re_replace}
CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE ${_re_match} ${_re_replace}
CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REGEX REPLACE ${_re_match} ${_re_replace}
CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string(REGEX REPLACE ${_re_match} ${_re_replace}
CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
string(REGEX REPLACE ${_re_match} ${_re_replace}
CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
endif()
Run Code Online (Sandbox Code Playgroud)
如果使用其他语言(即C),那么也需要添加这些语言。
| 归档时间: |
|
| 查看次数: |
28370 次 |
| 最近记录: |