如果编译器支持C++ 11,有没有办法让CMake自动检测?
因为在CMake运行期间通知用户会因为编译器不支持C++ 11而无法编译代码会很好.目前我设置了C++ 11标志.但是,如果编译器不支持它,则用户在CMake运行期间会收到编译错误而不是错误.
完美将是有效的东西find_package().但是,我没有找到任何提供所需功能的模块或功能.
另外,使用该功能检测编译器是否需要标志std=c++0x或更好std=c++11.
是否有可用的东西,或者我需要自己开发这个?
下面是我目前使用的一些代码,但它只适用于GNU'c GCC编译器.如果能有更通用的解决方案,那就太好了.
if(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
message(STATUS "C++11 activated.")
add_definitions("-std=gnu++11")
elseif(GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
message(WARNING "C++0x activated. If you get any errors update to a compiler which fully supports C++11")
add_definitions("-std=gnu++0x")
else ()
message(FATAL_ERROR "C++11 needed. Therefore a gcc compiler with a version higher than 4.3 is needed.")
endif()
else(CMAKE_COMPILER_IS_GNUCXX)
add_definitions("-std=c++0x")
endif(CMAKE_COMPILER_IS_GNUCXX)
Run Code Online (Sandbox Code Playgroud) 我在CMakeLists.txt中有以下内容:
project( Matfile )
SET ( CMAKE_CXX_FLAGS "-std=c++0x" )
set ( SOURCES
"foo.cpp"
"bar.cpp"
)
add_library(
Matfile
${SOURCES}
)
Run Code Online (Sandbox Code Playgroud)
您可能想象,我想要做的是使用标志-std = c ++ 0x编译我的C++源代码(我使用的是gcc,我需要C++ 11的功能).不幸的是,这不起作用,在我使用cmake生成makefile时,变量CMAKE_CXX_FLAGS完全无效.
如何在项目文件中设置此变量?
这似乎是一个非常愚蠢的问题,但我只花了不少于两个小时试图解决这个问题.
我一直在寻找一种可移植的方法来强制CMake启用编译器的C99功能,以避免出现以下gcc错误:
error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int s = 1; s <= in_para->StepNumber; s++){
^
Run Code Online (Sandbox Code Playgroud)
我也不想检查哪个编译器并附加如下内容:
set(CMAKE_C_FLAGS "-std=c99") # that would be bad
Run Code Online (Sandbox Code Playgroud)
所以我发现这篇文章:在CMake中启用C99以及相关的功能请求:0012300:CMake没有跨平台的方式来请求C99.在这个Mantis bug中,我了解了target_compiler_features之后我发现了这些SOF答案:如何在CMake中激活C++ 11?以及如何使用CMake检测编译器的C++ 11支持.
所以我的问题是:这target_compiler_features将提供一种需要C功能和C++功能的方法吗?现在最简单的方法是什么 - 我目前正在使用CMake 2.8.12.2.这target_compiler_features不是CMake的最新发行版本(3.0.0).你知道什么时候被释放吗?
我在cmake中配置了一个相当大的应用程序.我最近添加了几个利用C++ 0x功能的类,它打破了构建,因为cmake没有配置为使用C++ 0x支持进行编译.如何将其添加为cmake的选项?
我使用此处和此处的说明在Ubuntu中构建OpenWrt,但我得到:
make[4]: Entering directory '~/openwrt/build_dir/host/cmake-3.11.1/Bootstrap.cmk'
make[4]: 'cmake' is up to date.
make[4]: Leaving directory '~/openwrt/build_dir/host/cmake-3.11.1/Bootstrap.cmk'
loading initial cache file ~/openwrt/build_dir/host/cmake-3.11.1/Bootstrap.cmk/InitialCacheFlags.cmake
CMake Error at CMakeLists.txt:92 (message):
The C++ compiler does not support C++11 (e.g. std::unique_ptr).
-- Configuring incomplete, errors occurred!
Run Code Online (Sandbox Code Playgroud)
这里有一个类似问题的解决方案。但是,我不清楚哪个CMakeLists.txt文件是我的情况下的“根”。我在 OpenWrt 论坛(或一般搜索引擎)上没有看到太多关于此失败的信息。
我得到的印象是 CMake 安装是由 OpenWrt 构建器本身下载的,因为我没有安装 CMake 并且安装 CMake 没有解决任何问题。
尝试查看最新的 OpenWrt v18.06.2。当构建失败时,我删除了克隆的目录并尝试了 v18.06.0-rc2。没有任何改善。
我也尝试过
export CMAKE_CXX_STANDARD=11
Run Code Online (Sandbox Code Playgroud)
在运行“make”之前,但它没有解决问题。
我的 g++ 安装状态:
g++ -v
Run Code Online (Sandbox Code Playgroud)
输出:
Using built-in specs.
COLLECT_GCC=g++ …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个CMakeFiles.txt(以前从未这样做过),我不确定用于C++ 11的编译器标志是什么.我使用GCC 4.8.2,标志是std = c ++ 0x,但我不知道如何处理其他编译器.我不认为他们都使用那个标志,我相信MinGW-TDM使用std = c ++ 11,确保编译器使用c ++ 11的正确方法是什么?
我使用了 Qt 5.7 和 gcc 4.9.2。Qt 核心模块抛出Qt requires C++11 support错误。
这个页面说
gcc 4.9.2 无法编译 Qt。
所以我安装了 gcc 4.8。我在终端上使用以下命令进行检查:
$ g++ --version
g++ (Ubuntu 4.8.4-1ubuntu15) 4.8.4
Run Code Online (Sandbox Code Playgroud)
我的工具包使用 cmake 而不是 qmake。我添加 TARGET_LINK_LIBRARIES ( xxxx yyyy /usr/bin/c++ -std=c++11 到 CMakeLists-txt。
我重新启动我的电脑并再次运行我的应用程序。抛出同样的错误。
/opt/Qt/5.7/gcc_64/include/QtCore/qbasicatomic.h:61: error: #error "Qt requires C++11 support"
# error "Qt requires C++11 support"
^
Run Code Online (Sandbox Code Playgroud)
我该如何解决?
所以在我的VS2010上我可以编译代码如下:
boost::shared_ptr<boost::thread> internal_thread;
boost::packaged_task<void> internal_task_w(boost::bind(&thread_pool::internal_run, this, internal_thread));
internal_thread = boost::shared_ptr<boost::thread>( new boost::thread(std::move(internal_task_w)));
Run Code Online (Sandbox Code Playgroud)
使用boost 1.47.0和linux ...前两行是正常的但是在std :: move它给出了error: ‘move’ is not a member of ‘std’.在VS2010上它不需要任何特殊标头.所以我想知道它在Linux上需要哪个头,无论如何它都在STD中吗?如果不是如何通过提升或其他东西绕过它?
感谢所有提供帮助的人!最终起作用的是改变:
set(CMAKE_CXX_COMPILER "gcc-10")
set(CMAKE_C_COMPILER "g++-10")
Run Code Online (Sandbox Code Playgroud)
到:
set(CMAKE_CXX_COMPILER "/usr/local/opt/llvm/bin/clang")
set(CMAKE_C_COMPILER "/usr/local/opt/llvm/bin/clang++")
Run Code Online (Sandbox Code Playgroud)
尝试将 boost 链接到我的程序时出现以下错误:
[ 83%] Linking CXX executable cartogram
Undefined symbols for architecture x86_64:
"__ZN5boost15program_options11to_internalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
__ZN5boost15program_options11to_internalINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESt6vectorIS7_SaIS7_EERKS8_IT_SaISB_EE in main.cpp.o
"__ZN5boost15program_options16validation_error12get_templateB5cxx11ENS1_6kind_tE", referenced from:
__ZN5boost15program_options10validators17get_single_stringIcEERKNSt7__cxx1112basic_stringIT_St11char_traitsIS5_ESaIS5_EEERKSt6vectorIS9_SaIS9_EEb in main.cpp.o
"__ZN5boost15program_options19options_descriptionC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjj", referenced from:
_main in main.cpp.o
"__ZN5boost15program_options20invalid_option_valueC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
__ZN5boost15program_options8validateIicEEvRNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIT0_St11char_traitsIS7_ESaIS7_EEESaISB_EEPT_l in main.cpp.o
"__ZN5boost15program_options22error_with_option_nameC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_i", referenced from:
__ZN5boost15program_options10validators17get_single_stringIcEERKNSt7__cxx1112basic_stringIT_St11char_traitsIS5_ESaIS5_EEERKSt6vectorIS9_SaIS9_EEb in main.cpp.o
"__ZN5boost15program_options3argB5cxx11E", referenced from:
__ZNK5boost15program_options11typed_valueIbcE4nameB5cxx11Ev in main.cpp.o
__ZNK5boost15program_options11typed_valueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcE4nameEv in main.cpp.o
__ZNK5boost15program_options11typed_valueIicE4nameB5cxx11Ev in main.cpp.o
"__ZN5boost15program_options6detail7cmdline21set_additional_parserENS_9function1ISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ERKSA_EE", referenced from:
__ZN5boost15program_options25basic_command_line_parserIcE12extra_parserENS_9function1ISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ERKSA_EE in main.cpp.o
"__ZN5boost15program_options6detail7cmdlineC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE", referenced from:
__ZN5boost15program_options25basic_command_line_parserIcEC1EiPKPKc in main.cpp.o
"__ZN5boost15program_options8validateERNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEPS9_i", referenced …Run Code Online (Sandbox Code Playgroud) 编译我的程序后
$ cmake .
$ make
Run Code Online (Sandbox Code Playgroud)
我收到这种形式的 5 个错误:
$ make
Scanning dependencies of target Project
[ 50%] Building CXX object CMakeFiles/myproj.dir/main.cpp.o
In file included from /path/to/my/proj/main.cpp:2:0:
/path/to/my/proj/library.hpp: In member function ‘virtual double MyProjClass::get_value(double, double) const’:
/path/to/my/proj/library.hpp:419:26: error: ‘sqrtf’ is not a member of ‘std’
const float F = (std::sqrtf(1.0f + 2.0f) - 1.0f) / 2;
^
Run Code Online (Sandbox Code Playgroud)
其他错误包括floorf不是std.
查看此线程,这是因为我没有使用 C++11 进行编译,而查看此线程线程,“[...] CMake 将确保使用适当的命令行标志调用 C++ 编译器。”
好吧,我的 CMake 显然没有这样做。为什么我会收到这些错误,我该如何修复它们?
编辑:这是我的 CMakeLists.txt
cmake_minimum_required(VERSION 3.5) …Run Code Online (Sandbox Code Playgroud) 当我使用 clang 来格式化我的 C++ 代码时,我遇到了一个问题:
priority_queue<int, vector<int>, greater<int> > q;
Run Code Online (Sandbox Code Playgroud)
将自动格式化为:
priority_queue<int, vector<int>, greater<int>> q;
Run Code Online (Sandbox Code Playgroud)
两个单独的 '>' 将被格式化为一个移位 >>。
那么我应该如何配置.clang-format文件来避免这种情况呢?
我知道C ++有标准而不是版本,因此,它们的发布由规范管理(例如C99,C ++ 11等)
C ++编译器具有版本,并且每个版本都可以支持多种c ++标准。
关于上述内容,我找到了我的g ++版本编译器,即7.2.0
? bgarcial [~] ? g++ --version
g++ (Ubuntu 7.2.0-8ubuntu3) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
? bgarcial [~] ?
Run Code Online (Sandbox Code Playgroud)
我的g ++编译器具有以下目录,我正在使用本机Makefile以C ++语言进行构建
? bgarcial [include/c++/7] ? pwd
/usr/include/c++/7
? bgarcial [include/c++/7] ?
Run Code Online (Sandbox Code Playgroud)
如何确定我的g ++编译器支持哪些C ++标准?
所述克++文档包括以下信息:
GCC支持1998年发布的原始ISO C ++标准以及2011和2014年的修订版。如果未提供C ++语言方言选项,则默认值为-std = gnu ++ …