我是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
答案 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_STANDARD
和CXX_STANDARD_REQUIRED
属性的支持。
CXX_STANDARD
:取CMAKE_CXX_STANDARD
个98, 11 and 14
个值,CXX_STANDARD 11
。
如果传递CXX_STANDARD
并且编译器不支持c ++ 11
CXX_STANDARD_REQUIRED
自动变为98,cmake不会给你任何
如果OFF
为CXX_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
)