cmake不会编译为C ++ 11标准

问题描述 投票:8回答:4

我是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()
#####################################

正如你所看到的,我正在使用覆盆子pi玩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命令”。

其他细节: - 在Rasberry上编译pi 3运行debian jessie -CXX编译器是GNU 4.9.2 -CMAKE 3.0.2

c++ c++11 cmake
4个回答
30
投票

在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支持不完整,并且可能存在与定义的标准不同的行为。


4
投票

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你需要处理复杂而不是编译器的可移植标志sush as:

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)

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")

0
投票

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

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

target_compile_features(engine
    PRIVATE cxx_range_for
    )
© www.soinside.com 2019 - 2024. All rights reserved.