cmake将无法编译为C ++ 11标准

时间:2016-06-03 18:38:58

标签: c++ c++11 cmake

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

使用C ++ 11功能的简单c ++程序,例如统一初始化,线程,to_string等......会产生" xxx"未在范围中声明。具体来说,我现在要使用to_string,并在std命名空间中使用它或专门std::to_string创建错误" to_string"不是STD的成员。很明显,它没有用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

4 个答案:

答案 0 :(得分:30)

在CMake版本早于3.1 时,我们使用

 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文档,然后看起来像这样:

set_target_properties(myTarget PROPERTIES
    CXX_STANDARD 11
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS OFF
)

编辑但请注意,GCC 4中的C ++ 11支持不完整,可能会出现与定义标准不同的行为。

答案 1 :(得分:4)

CMake在3.1版本上添加对CXX_STANDARDCXX_STANDARD_REQUIRED属性的支持。 CXX_STANDARD:取CMAKE_CXX_STANDARD98, 11 and 14个值,CXX_STANDARD 11。 如果传递CXX_STANDARD并且编译器不支持c ++ 11 CXX_STANDARD_REQUIRED自动变为98,cmake不会给你任何 如果OFFCXX_STANDARD_REQUIRED "ON" CXX_STANDARD或未设置,则会出错。 如果您的set CHECK_CXX_COMPILER_FLAG特定值成为构建和cmake处理此属性的必需属性。

使用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) 使用你需要包含CheckCXXCompilerFlag模块:

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)

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

Company

答案 2 :(得分:0)

我总是在我的代码中使用CMake启用c ++ 11:

set(CMAKE_CXX_FLAGS "-std=c++11")

我的编译器是gcc(Debian 4.9.2-10)4.9.2,但是在我的工作场所我也使用其他版本,这种方法总是有效。

编辑(以避免变量覆盖):

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

答案 3 :(得分:0)

由于当前的cmake版本是3.10,我认为识别更新的方法可能是合适的。虽然建议使用add_compiler _

对于在这里看到更现代版本的cmake(3.1+)的人来说,最合适的答案不是识别给定编译器的版本,而是让CMAKE知道需要提供哪些功能。

target_compile_features(engine
    PRIVATE cxx_range_for
    )