cmake 不会编译为 C 11 标准

新手上路,请多包涵

我是 C++ 的新手,一直在努力编译/制作/链接/构建/任何东西,让我们看看是否有人可以帮助我。我做了一些搜索,发现其他人有类似的问题,但我尝试了他们的解决方案,但没有运气,所以这里是:

使用 C++ 11 功能(例如统一初始化、线程、 to_string 等)的简单 c++ 程序会生成 未在范围内声明“xxx”的 错误。具体来说,现在我想使用 to_string ,并在 std 命名空间中使用它,或者特别是 std::to_string 创建错误 _“to_string”不是性病_。很明显它不是用 C++ 11 编译的。

所以这是我的make文件:

 #####################################
cmake_minimum_required (VERSION 2.8)
project (raspicam_test)
find_package(raspicam REQUIRED)
find_package(OpenCV)

IF  ( OpenCV_FOUND AND raspicam_CV_FOUND)
        MESSAGE(STATUS "COMPILING OPENCV TESTS")
        add_executable (main main.cpp)
        #target_compile_features(main PRIVATE cxx_range_for)
        set_property(TARGET main PROPERTY CXX_STANDARD 11)
        target_link_libraries (main ${raspicam_CV_LIBS})
ELSE()
        MESSAGE(FATAL_ERROR "OPENCV NOT FOUND IN YOUR SYSTEM")
ENDIF()
#####################################

如您所见,我正在树莓派上使用 OpenCV。但是没有 C++11 函数,程序编译和运行没有问题。但我想从 C++11 添加线程和其他好东西。根据 CMAKE 文档,我添加了 set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED 11) 行:

https://cmake.org/cmake/help/v3.1/prop_tgt/CXX_STANDARD.html

它对产生的错误没有任何影响。我首先在没有 _REQUIRED 的情况下完成了它,然后再使用它。我也尝试 target_compile_features() 但 CMAKE 返回了“未知的 CMAKE 命令”。

其他细节: - 在运行 debian jessie 的树莓派 3 上编译 -CXX 编译器是 GNU 4.9.2 -CMAKE 3.0.2

原文由 DrTarr 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

3.1 之前的 CMake 版本中,我们使用

 add_compile_options(-std=c++11) # CMake 2.8.12 or newer

CMake Docs 中所述,将编译选项添加到编译器调用。

这可能不像 Alvaro 的答案那样可移植,但它更具可读性,而且因为你在 RasPi 上,我猜,GCC 和 Clang 作为目标编译器会做。

编辑: 为了完整起见:在 CMake 版本 3.1 和更新版本 中,如果要强制使用 C++11,则需要以下几行:

 set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11

这会在编译期间启用此声明之后的所有目标的选项。如果您想控制更细粒度,请参阅 Alvaro 的答案或 set_taget_properties() 的 CMake Docs,然后看起来像这样:

 set_target_properties(myTarget PROPERTIES
    CXX_STANDARD 11
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS OFF
)

编辑: 但请注意,GCC 4 中的 C++11 支持并不完整,并且可能存在与定义标准不同的行为。

原文由 user6214440 发布,翻译遵循 CC BY-SA 4.0 许可协议

CMake 在 3.1 版本上添加了对 CXX_STANDARDCXX_STANDARD_REQUIRED 属性的支持。 CXX_STANDARD :取 CMAKE_CXX_STANDARD 值之一,它们是 98, 11 and 14 。如果您通过 CXX_STANDARD 11 并且您的编译器不支持 c++11 CXX_STANDARD 自动变为 98 并且如果 CXX_STANDARD_REQUIREDOFF 则 cmake 不会给您任何错误 --- 或未设置。如果您的设置 CXX_STANDARD_REQUIRED "ON" CXX_STANDARD 特定值成为构建和 cmake 处理此所需的属性。

为了使用 CHECK_CXX_COMPILER_FLAG 你需要包含 CheckCXXCompilerFlag 模块:

 include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
    message(STATUS "${COMPILER_SUPPORTS_CXX11}")
else(COMPILER_SUPPORTS_CXX11)
    message(FATAL_ERROR "${COMPILER_SUPPORTS_CXX11}")
endif(COMPILER_SUPPORTS_CXX11)

如果你有一个旧的 cmake,你需要处理来自编译器的复杂而不是可移植的标志:

 function(suported_compilers)
  if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
    execute_process(
      COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
    if(NOT(GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
      message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.")
    endif(NOT(GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
  elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
  else()
    message(FATAL_ERROR "Your compiler is supported in the build set?, please "
                  "contact the maintainer.")
  endif()
endfunction(suported_compilers)
function(set_targets_compilers_flags target_list)
  suported_compilers()
  foreach(tg ${target_list})
    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
      set_target_properties(${tg} PROPERTIES COMPILE_FLAGS "-g -std=c++14 -Wall -Wextra -Werror")
    elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
      set_target_properties(${tg} PROPERTIES COMPILE_FLAGS "/W4 /WX /EHsc")
    endif()
  endforeach()
endfunction(set_targets_compilers_flags)

原文由 Alvaro Denis Acosta 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题