将 std::filesystem 添加到 CMake 项目时出现问题

新手上路,请多包涵

我是 CMake 项目的新手,我想在我的项目中使用文件系统库。我正在运行带有 GCC 8.2 和 CMake 3.13 的 Ubuntu 18.04。为了实现这一点,我尝试了两种选择:

选项1

 cmake_minimum_required(VERSION 3.13)
project(TheFsProject)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-std=c++17 -lstdc++fs")

这无济于事,因为编译器在编译期间仍然无法找到文件系统库。

选项 2 (复制自: https ://www.scivision.co/cmake-cpp-17-filesystem/)

 make_minimum_required(VERSION 3.13)
project(TheFsProject)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_REQUIRED_FLAGS -std=c++17)
include(CheckCXXSymbolExists)
CHECK_CXX_SYMBOL_EXISTS(std::filesystem::path::preferred_separator cxx17fs)

if(cxx17fs)
  add_executable(TheFsProject main.cpp)
  set_property(TARGET TheFsProject PROPERTY CXX_STANDARD 17)
endif()

这也无济于事,因为我收到了一个我不明白的 CMake 错误。

 (CHECK_CXX_SYMBOL_EXISTS):
 CHECK_CXX_SYMBOL_EXISTS Macro invoked with incorrect arguments for macro named: CHECK_CXX_SYMBOL_EXISTS

我对这个话题感觉不够深入,这就是我来这里的原因。我不介意付出额外的努力来了解更多信息,但我不知道该去哪里找了。任何帮助,将不胜感激!

编辑 1

感谢您到目前为止的回复!我根据您的反馈制作了 选项 3

 cmake_minimum_required(VERSION 3.13)
project(TheFsProject)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(TheFsProject main.cpp)
target_link_libraries(TheFsProject stdc++fs)

可悲的是它不能解决我的问题。它在编译过程中仍然会发出一个错误,它找不到编译头。

编辑 2

感谢到目前为止的所有回复。所有这些都有帮助。我最后尝试了 Ashkan 他的回答(因为它看起来很吓人)。这个返回

编译器缺少文件系统功能。

所以我猜这方面出了点问题。这很有用,因为我现在知道这可能不是由于我的 CMake 文件。我现在必须找出为什么编译器确实支持文件系统头……

编辑 3

严格来说,这个问题得到了回答,因为我的问题是关于 CMake 文件的。我将把 Ashkan 的答案标记为解决方案,因为它在我的故障排除搜索中产生了下一步。如果可以的话,我也会标记 lubgr 他的答案,因为我认为这也是一个非常好的答案。感谢大家!

原文由 MaestroMaus 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.8k
2 个回答

除了@lubgr的回答。我认为更完整的方法是也执行 try_compile 以查看您是否可以实际使用文件系统标头。我认为这更好,因为一些编译器还不支持 std::filesystem 。同样在 gcc 7.x 中,您的文件系统位于 experimental 命名空间下。这样,您可以在 else 子句中有一个单独的 try_compile 并检测到它。

这是它的相关cmake

 # set everything up for c++ 17 features
set(CMAKE_CXX_STANDARD 17)
# Don't add this line if you will try_compile with boost.
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# test that filesystem header actually is there and works
try_compile(HAS_FS "${CMAKE_BINARY_DIR}/temp"
"${CMAKE_SOURCE_DIR}/tests/has_filesystem.cc"
            CMAKE_FLAGS -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON
            LINK_LIBRARIES stdc++fs)
if(HAS_FS)
    message(STATUS "Compiler has filesystem support")
else()
#   .... You could also try searching for boost::filesystem here.
    message(FATAL_ERROR "Compiler is missing filesystem capabilities")
endif(HAS_FS)

文件tests/has_filesystem.cc 很简单

#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    fs::path aPath {"../"};

    return 0;
}

您可以在 else 子句中 try_compile for boost::filesystem 并传递一个可在源文件中使用的指令,您可以在其中决定是否要使用 c++17 文件系统或 boost。

原文由 Ashkan 发布,翻译遵循 CC BY-SA 4.0 许可协议

海合会 8.2。附带 <filesystem> ,因此无需调查可用性。接下来,选项 1 就足够了,但需要修复:

 set(CMAKE_CXX_STANDARD 17) # no need to manually adjust the CXXFLAGS

add_executable(yourExecutable yourSourceFile.cpp)

target_link_libraries(yourExecutable stdc++fs)

这应该会导致使用 -std=c++17-std=gnu++17 编译源代码,并在链接时添加 -lstdc++fs

编辑:请注意,正如@Ashkan 在评论中指出的那样,如果编译器不支持 C++17,将 CMAKE_CXX_STANDARD_REQUIRED 设置为 true 会导致在配置时立即出现错误,而不是编译错误(由于缺少 <filesystem> 标头)或在链接时(由于缺少共享库)。这可能是可取的。

原文由 lubgr 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题