cmake 不会编译为 C++ 11 标准
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37621342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
cmake will not compile to C++ 11 standard
提问by DrTarr
I'm new to C++ and have been struggling with compiling/making/linking/building/whatever, lets see if somebody can help me out. I did some searches and found other people with similar problems but I tried their solutions with no luck, so here goes:
我是 C++ 的新手,一直在努力编译/制作/链接/构建/任何东西,让我们看看是否有人可以帮助我。我做了一些搜索,发现其他人也有类似的问题,但我尝试了他们的解决方案但没有运气,所以这里是:
A simple c++ program that uses C++ 11 functionality such as uniform initialization, threads, to_string
, etc... generates errors that "xxx" was not declared in the scope. Specifically right now I'd like to use to_string
, and using it in the std
namespace or specifically std::to_string
creates the error "to_string" is not a member of STD. So clearly it's not compiling with C++ 11.
使用 C++ 11 功能(例如统一初始化、线程to_string
等)的简单 C++ 程序会生成错误,指出“xxx”未在作用域中声明。特别是现在我想使用to_string
, 并在std
命名空间中使用它或专门std::to_string
创建错误"to_string" is not a member of STD。很明显,它不是用 C++ 11 编译的。
So here's my make file:
所以这是我的制作文件:
#####################################
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()
#####################################
As you can see I'm playing around with OpenCV on a raspberry pi. But without the C++11 functions the program compiles and runs no issues. But I would like to add threads and other goodies from C++11. I added the line set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED 11)
according to the CMAKE documentation:
如您所见,我正在树莓派上使用 OpenCV。但是没有 C++11 函数,程序编译和运行都没有问题。但我想从 C++11 添加线程和其他好东西。我set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED 11)
根据 CMAKE 文档添加了该行:
https://cmake.org/cmake/help/v3.1/prop_tgt/CXX_STANDARD.html
https://cmake.org/cmake/help/v3.1/prop_tgt/CXX_STANDARD.html
And it made no difference in the errors generated. I did it first without the _REQUIRED
and then with it. I also tried target_compile_features()
instead but CMAKE returned with "unknown CMAKE command".
它对生成的错误没有影响。我先不_REQUIRED
使用它,然后使用它。我也尝试过,target_compile_features()
但 CMAKE 返回了“未知的 CMAKE 命令”。
Other details: -Compiling on a raspberry pi 3 running debian jessie -CXX compiler is GNU 4.9.2 -CMAKE 3.0.2
其他详细信息:-在运行 debian jessie 的 raspberry pi 3 上编译 -CXX 编译器是 GNU 4.9.2 -CMAKE 3.0.2
回答by Bugfinger
In CMake versions earlier than 3.1, we use
在3.1 之前的CMake 版本中,我们使用
add_compile_options(-std=c++11) # CMake 2.8.12 or newer
to add compile options to the compiler call as described in the CMake Docs.
将编译选项添加到编译器调用中,如CMake Docs 中所述。
That's propably not as portable as the one in Alvaro's answer, but it's more readable and since you are on you RasPi, I guess, GCC and Clang as target compilers will do.
这可能不像 Alvaro 的答案那样可移植,但它更具可读性,而且由于您使用的是 RasPi,我猜 GCC 和 Clang 作为目标编译器会这样做。
Edit:For the sake of completeness: In CMake version 3.1 and newer, if you want to force C++11, you need the following lines:
编辑:为了完整起见:在 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
This enables the options for all targets during compilation. If you want to control this more fine-grained, see Alvaro's answer or the CMake Docs of set_taget_properties()
, which then looks something like this:
这会在编译期间启用所有目标的选项。如果您想更精细地控制它,请参阅 Alvaro 的答案或 CMake Docs of set_taget_properties()
,然后看起来像这样:
set_target_properties(myTarget PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
)
Edit:But beware that C++11 support in GCC 4 is not complete and there might be things that behave differently from the defined standard.
编辑:但请注意 GCC 4 中的 C++11 支持并不完整,并且可能存在与定义标准不同的行为。
回答by Alvaro Denis Acosta
CMake add support for CXX_STANDARD
and CXX_STANDARD_REQUIRED
properties on 3.1 version.
CXX_STANDARD
: Take one of CMAKE_CXX_STANDARD
values and they are 98, 11 and 14
.
If you pass CXX_STANDARD 11
and you compiler do not support c++11
CXX_STANDARD
become 98 automatically and cmake do not give you any
error if CXX_STANDARD_REQUIRED
is OFF
or unset.
If your set CXX_STANDARD_REQUIRED "ON" CXX_STANDARD
specific value become as a required property to build and cmake handle this.
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 并且 cmake 不会给你任何错误如果CXX_STANDARD_REQUIRED
是OFF
或未设置。如果您设置的CXX_STANDARD_REQUIRED "ON" CXX_STANDARD
特定值成为构建和 cmake 处理此问题的必需属性。
In orde to use CHECK_CXX_COMPILER_FLAG
you nedd to include CheckCXXCompilerFlag module:
为了使用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)
If you have a old cmake you need handle complicate and not portable flags from compilers sush as:
如果您有一个旧的 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)
回答by pptaszni
I always enable c++11 in my code using CMake this way:
我总是以这种方式使用 CMake 在我的代码中启用 c++11:
set(CMAKE_CXX_FLAGS "-std=c++11")
My compiler is gcc (Debian 4.9.2-10) 4.9.2, however in my workplace I also use other versions and this approach always works.
我的编译器是 gcc (Debian 4.9.2-10) 4.9.2,但是在我的工作场所我也使用其他版本,这种方法总是有效。
EDIT (to avoid variable overwriting):
编辑(以避免变量覆盖):
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
回答by Brian Bruggeman
Since the current cmake release is 3.10, I thought it may be appropriate to identify the newer method. While the suggestion to use add_compiler_
由于当前的 cmake 版本是 3.10,我认为识别较新的方法可能是合适的。虽然建议使用 add_compiler_
For anyone looking here at a more modern version of cmake (3.1+), The most appropriate answer is not to identify a version of a given compiler but to let CMAKE know what features need to be available.
对于在这里查看更现代版本的 cmake (3.1+) 的任何人来说,最合适的答案不是确定给定编译器的版本,而是让 CMAKE 知道需要提供哪些功能。
target_compile_features(engine
PRIVATE cxx_range_for
)