CMake配置Visual Studio 2019 C++17版本失败求助
我是CMake新手,一直尝试在CMake项目中设置C++17语言版本,但始终未能成功,怀疑遗漏了简单配置,导致CMakeLists.txt变得复杂。已查阅大量论坛资料并尝试多种设置组合,但均无效。
环境:64位Windows10、Visual Studio 2019社区版。已确认使用MSVC编译器,但通过测试代码输出显示当前仍为C98版本。恳请帮忙排查配置错误,指导正确设置C17的方法。
CMakeLists.txt代码
cmake_minimum_required (VERSION 3.16) project ("OpenCv") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") message("Using GCC compiler") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") message("Using Clang compiler") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") message("Using MSVC compiler") else () message("Unknown compiler: ${CMAKE_CXX_COMPILER_ID}") endif () set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) include (CTest) enable_testing() find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) # Add source to this project's executable. add_executable (OpenCv "OpenCv.cpp" "OpenCv.h" "FrameBuffer.cpp" "FrameBuffer.h" "Mats.h") target_compile_definitions(OpenCv PRIVATE _ALLOW_RTCc_IN_STL) if(MSVC) target_compile_options(OpenCv PRIVATE "/std:c++17") else() target_compile_features(OpenCv PRIVATE cxx_std_17) endif() target_link_libraries(OpenCv ${OpenCV_LIBS}) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(cpack)
CmakeSettings.json代码
{ "configurations": [ { "name": "x64-Debug", "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x64_x64" ], "buildRoot": "${projectDir}\\out\\build\\${name}", "installRoot": "${projectDir}\\out\\install\\${name}", "cmakeCommandArgs": "", "buildCommandArgs": "-v", "ctestCommandArgs": "", "variables": [ { "name": "CMAKE_CXX_FLAGS", "value": "/DWIN32 /D_WINDOWS /W3 /GR /EHsc /std:c++17", "type": "STRING" }, { "name": "CMAKE_CXX_FLAGS_DEBUG", "value": "/MDd /Zi /Ob0 /Od /RTC1/std:c++17", "type": "STRING" } ] } ] }
测试代码
if (__cplusplus == 202101L) std::cout << "C++23"; else if (__cplusplus == 202002L) std::cout << "C++20"; else if (__cplusplus == 201703L) std::cout << "C++17"; else if (__cplusplus == 201402L) std::cout << "C++14"; else if (__cplusplus == 201103L) std::cout << "C++11"; else if (__cplusplus == 199711L) std::cout << "C++98"; else std::cout << "pre-standard C++." << __cplusplus; std::cout << "\n";
测试输出
C++98
配置中存在几个关键问题,逐一修复即可解决:
CmakeSettings.json参数格式错误
CMAKE_CXX_FLAGS_DEBUG的值里,/RTC1/std:c++17是错误写法——编译器会把它识别为单个无效参数,正确应该用空格分隔:/MDd /Zi /Ob0 /Od /RTC1 /std:c++17。这个错误直接导致C++17标准开关不生效。CMakeLists.txt冗余配置引发冲突
你已经通过全局变量CMAKE_CXX_STANDARD 17等设置了C++标准,无需再针对MSVC单独添加/std:c++17选项,也不需要用target_compile_features重复声明。冗余配置可能导致优先级冲突,建议删除以下代码块:if(MSVC) target_compile_options(OpenCv PRIVATE "/std:c++17") else() target_compile_features(OpenCv PRIVATE cxx_std_17) endif()MSVC下__cplusplus宏的特殊处理
MSVC默认不会将__cplusplus宏更新为对应标准的数值,哪怕已经启用了C17,它仍会显示199711L(对应C98)。必须添加/Zc:__cplusplus编译选项才能让宏值正确匹配当前标准,在CMakeLists.txt中添加:if(MSVC) add_compile_options("/Zc:__cplusplus") endif()清理旧构建缓存
之前错误配置生成的缓存文件会影响新配置,务必删除out/build/x64-Debug目录,再重新生成CMake配置并编译。
修复后的CMakeLists.txt(简化版)
cmake_minimum_required (VERSION 3.16) project ("OpenCv") # 检测编译器 if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") message("Using GCC compiler") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") message("Using Clang compiler") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") message("Using MSVC compiler") # MSVC需要添加该选项才能正确显示__cplusplus宏 add_compile_options("/Zc:__cplusplus") else () message("Unknown compiler: ${CMAKE_CXX_COMPILER_ID}") endif () # 全局设置C++17标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) include (CTest) enable_testing() find_package(OpenCV REQUIRED) # 使用target_include_directories替代全局include_directories,更符合现代CMake规范 add_executable (OpenCv "OpenCv.cpp" "OpenCv.h" "FrameBuffer.cpp" "FrameBuffer.h" "Mats.h") target_compile_definitions(OpenCv PRIVATE _ALLOW_RTCc_IN_STL) target_include_directories(OpenCv PRIVATE ${OpenCV_INCLUDE_DIRS}) target_link_libraries(OpenCv PRIVATE ${OpenCV_LIBS}) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(cpack)
修复后的CmakeSettings.json
{ "configurations": [ { "name": "x64-Debug", "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x64_x64" ], "buildRoot": "${projectDir}\\out\\build\\${name}", "installRoot": "${projectDir}\\out\\install\\${name}", "cmakeCommandArgs": "", "buildCommandArgs": "-v", "ctestCommandArgs": "", "variables": [ { "name": "CMAKE_CXX_FLAGS", "value": "/DWIN32 /D_WINDOWS /W3 /GR /EHsc /std:c++17", "type": "STRING" }, { "name": "CMAKE_CXX_FLAGS_DEBUG", "value": "/MDd /Zi /Ob0 /Od /RTC1 /std:c++17", "type": "STRING" } ] } ] }
完成以上修复后,重新生成项目并编译,测试代码应该会输出C++17。
内容的提问来源于stack exchange,提问作者Honey Hiccups

