我是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
在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支持不完整,并且可能存在与定义的标准不同的行为。
CMake在3.1版本上添加了对CXX_STANDARD
和CXX_STANDARD_REQUIRED
属性的支持。 CXX_STANDARD
:取CMAKE_CXX_STANDARD
值之一,他们是98, 11 and 14
。如果您通过CXX_STANDARD 11
并且您的编译器不支持c ++ 11 CXX_STANDARD
自动变为98并且如果CXX_STANDARD_REQUIRED
是OFF
或未设置,则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)
我总是使用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")
由于当前的cmake版本是3.10,我认为识别更新的方法可能是合适的。虽然建议使用add_compiler_
对于任何看到更现代版本的cmake(3.1+)的人来说,最合适的答案不是识别给定编译器的版本,而是让CMAKE知道需要提供哪些功能。
target_compile_features(engine
PRIVATE cxx_range_for
)