目标要求使用带编译器扩展的"CXX17"语言方言,但CMake不知道使用哪些编译标志来启用它。

15

我一直在尝试将<filesystem>添加到我的项目中,但这似乎比我想象的更麻烦。<filesystem>应该是C++17的一部分,我需要将该定义添加到我的CMakeList中。

我的根CMakeLists如下所示:

MESSAGE(“In src CMAKELIST”)

#
# Build everything in include/ directory
add_subdirectory(include)
#

#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

## Main executable target
add_executable(cmakeDemo main.cpp)

# These libraries get built in include/*/, CMake will auto-set required
# compiler flags and include paths from their definitions
target_link_libraries(cmakeDemo record ${portaudio})
target_link_libraries(cmakeDemo database)
target_link_libraries(cmakeDemo match)
target_link_libraries(cmakeDemo spectogram)

我添加了C++17的定义,但当编译我的系统时,出现以下错误:

 make 
“InsrcCMAKELIST”
“InincludeCMAKELIST”
“IndatabaseCMAKELIST”
“InmatchCMAKELIST”
“InrecordCMAKELIST”
“InspectogramCMAKELIST”
/home/lamda/soundcloud/src/include/spectogram/base/base.h
“outspectogramCMAKELIST”
-- Configuring done
CMake Error in src/CMakeLists.txt:
  Target "cmakeDemo" requires the language dialect "CXX17" (with compiler
  extensions), but CMake does not know the compile flags to use to enable it.


-- Generating done
-- Build files have been written to: /home/lamda/soundcloud/build
make: *** [cmake_check_build_system] Error 1

但是为什么不愿意使用C++17,以便我可以使用filesystem库呢?为什么?


3
你使用的是哪个版本的cmake?只有从v3.8开始,才支持将17作为“CMAKE_CXX_STANDARD”的值。 - user7860670
我正在使用cmake 3.9.6。我更新了cmake,因为这个原因...但是解决这个问题的方法似乎也是升级gcc和g++。 - Lamda
http://ovenproof-linux.blogspot.dk/2016/09/upgrade-gcc-and-g-in-ubuntu.html - Lamda
@Lamda 如果你已经找到了解决方案,那么你应该将其发布为答案并最终接受它。 - tambre
4个回答

20

如上所述,C++17仅受到cmake版本> 3.8的支持,因此我不得不对其进行更新。

但我的问题是我的gcc和g ++不支持它,因此我不得不更新它们,这是我之后做的。

我遵循了指南


11

我也遇到了同样的问题,虽然答案是一个好的开端,但对我来说还不够。

以下是我如何解决这个问题(在centos7发行版上):

1. CMAKE > 3.8

在CentOS上,'sudo yum info cmake'显示的版本为'2.8.12',因此我必须按照这些指示操作:https://cmake.org/download/,以获得'3.14.5'版本的CMake。

2. GCC/C++17 > 5.1.0

正如@Lamda所提到的,需要更新工具链,否则您将仍然卡在相同的错误消息上。

以下是CMAKE检查支持方言的方法: https://github.com/Kitware/CMake/blob/master/Modules/Compiler/GNU-CXX.cmake#L45

if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
  set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17")
  set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
  set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
  set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
endif()

再次尝试了CentOS,但运行'sudo yum info gcc'指令显示版本为'4.8.5'

于是我决定直接从源代码编译GCC,类似于以下方式:

wget ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/gcc-7.2.0/gcc-7.2.0.tar.gz
tar -xvzf gcc-7.2.0.tar.gz
cd gcc-7.2.0
./contrib/download_prerequisites
./configure \
    --enable-bootstrap \
    --enable-languages=c,c++,fortran,lto \
    --with-bugurl=http://bugzilla.redhat.com/bugzilla \
    --enable-shared \
    --enable-threads=posix \
    --enable-checking=release \
    --disable-multilib \
    --with-system-zlib \
    --enable-__cxa_atexit \
    --disable-libunwind-exceptions \
    --enable-gnu-unique-object \
    --enable-linker-build-id \
    --with-gcc-major-version-only \
    --enable-plugin \
    --with-linker-hash-style=gnu \
    --enable-initfini-array \
    --enable-libmpx \
    --enable-gnu-indirect-function \
    --with-tune=generic \
    --build=x86_64-redhat-linux
make -j4
sudo make install
sudo sh -c 'echo /usr/local/lib > /etc/ld.so.conf.d/1-gcc.conf'
sudo sh -c 'echo /usr/local/lib64 >> /etc/ld.so.conf.d/1-gcc.conf'
sudo ldconfig -v

因此,我最终使用GCC 7.2.0版本结束。
如果成功,以下测试应返回201402L
g++ -dM -E -x c++ /dev/null | grep -F __cplusplus

3. 仍然出现“方言”CXX17错误吗?

在我的情况下,需要采取其他措施才能使其工作:

sudo ln -s /usr/local/bin/gcc /usr/local/bin/cc

为什么?你可能会问...

GCC.7.2.0实际上似乎没有带有'cc'的符号链接 (这应该是指向'gcc'的一个简单符号链接)

另一方面,CMAKE通过使用'cc'路径(作为提示)来确定'g++'路径

在我的情况下,我仍然有一个/bin/cc #4.8.5/bin/g++ #4.8.5

所以即使现在存在一个/usr/local/bin/g++ #7.2.0 (应该优先使用)

CMAKE将不幸地使用/bin/g++ #4.8.5代替它

但是,显然最佳做法是删除整个旧的GCC工具链。


3
我已经将"-DCMAKE_C_COMPILER=/usr/local/bin/gcc" 和 "-DCMAKE_CXX_COMPILER=/usr/local/bin/g++" 添加到cmake命令选项中,运行良好。 - Mathieu CARBONNEAUX
1
EPEL存储库提供最新的CMake版本(软件包名称为“cmake3”,可执行文件也是如此)。 - To마SE

3

关于gcc的更新

从源代码构建我们自己的GCC实际上是一个坏主意...

在我的情况下,我尝试链接一个外部库(即使使用相同的c++标准/GCC版本),会出现一些错误

最佳实践似乎是使用devtoolset yum包 https://www.softwarecollections.org/en/scls/rhscl/devtoolset-7/

看起来这个软件包已经通过包含一些Redhat补丁和配置开关来制作。所以,只要我们不知道使其正常工作的神奇配方,使用更官方的东西就有意义。

结论: 使用devtoolset yum包,而不是尝试从源代码编译GCC


0
不要编译gcc,在CentOS上可以安装devtoolset-8-gcc。
yum -y install devtoolset-8-gcc devtoolset-8-gcc-c++ devtoolset-8-binutils
sudo ln -s /opt/rh/devtoolset-8/root/usr/bin/gcc /usr/bin/cc
sudo ln -s /opt/rh/devtoolset-8/root/usr/bin/g++ /usr/bin/c++

使用sudo ln -s不是最佳实践,建议使用. /opt/rh/devtoolset-8/enable代替,因为它不会操作可能已经安装的RHEL/CentOS 7自带的C++编译器。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接