You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

解决方案

配置中存在几个关键问题,逐一修复即可解决:

  1. CmakeSettings.json参数格式错误
    CMAKE_CXX_FLAGS_DEBUG的值里,/RTC1/std:c++17是错误写法——编译器会把它识别为单个无效参数,正确应该用空格分隔:/MDd /Zi /Ob0 /Od /RTC1 /std:c++17。这个错误直接导致C++17标准开关不生效。

  2. 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()
    
  3. MSVC下__cplusplus宏的特殊处理
    MSVC默认不会将__cplusplus宏更新为对应标准的数值,哪怕已经启用了C17,它仍会显示199711L(对应C98)。必须添加/Zc:__cplusplus编译选项才能让宏值正确匹配当前标准,在CMakeLists.txt中添加:

    if(MSVC)
        add_compile_options("/Zc:__cplusplus")
    endif()
    
  4. 清理旧构建缓存
    之前错误配置生成的缓存文件会影响新配置,务必删除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:59:57