【问题标题】:std::filesystem and std::experimental::filesystem problem in different compilers不同编译器中的 std::filesystem 和 std::experimental::filesystem 问题
【发布时间】:2019-09-10 23:13:28
【问题描述】:

我正在编写一个使用 std::filesystem 的库(仅用于学习)。它在 MSVC 上运行良好,但是默认情况下,Linux 的 LTS 版本(如 Ubuntu)附带 GCC 6.x,官方存储库中的 clang 是 3.8,它没有 std::filesystem 而我必须使用 std::experimental::filesystem。我该如何解决这个问题,以便我可以支持 GCC 6、GCC 8+(std::filesystem 工作的地方)、Clang 3.8、最新的 Clang 和 MSVC? 我使用 CMAKE 作为我的构建系统

【问题讨论】:

    标签: c++ c++11 visual-c++ cmake c++14


    【解决方案1】:

    条件编译可能会有所帮助:

    #if(defined(_MSC_VER) or (defined(__GNUC__) and (7 <= __GNUC_MAJOR__)))
    using n_fs = ::std::filesystem;
    #else
    using n_fs = ::std::experimental::filesystem;    
    #endif
    

    【讨论】:

    • 考虑到 FileSystem TS 和 C++17 版本之间存在显着差异,这可能会导致问题。
    • @NicolBolas 好吧,条件编译也可以帮助解决它们。
    【解决方案2】:

    我通过以下方式解决了我的问题:

    我在项目的 CMakeLists.txt 文件中添加了以下一堆代码

    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
        if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.4)
            message(FATAL_ERROR "You are on an extremely old version of GCC. Please update your compiler to at least GCC 5.4, preferably latest")
        elseif (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
            message(WARNING "Old Verison of GCC detected. Using Legacy C++ support")
            target_link_libraries(${PROJECT_NAME} -lstdc++fs)
            target_compile_definitions(${PROJECT_NAME} PUBLIC LEGACY_CXX)
        endif()
    endif()
    

    在我的 CPP 文件中,我这样做了:

    #ifdef LEGACY_CXX
    #include <experimental/filesystem>
    namespace n_fs = ::std::experimental::filesystem;
    #else
    #include <filesystem>
    namespace n_fs = ::std::filesystem;
    #endif
    

    Here's 提交,如果有人想参考。

    【讨论】:

      【解决方案3】:

      “我该如何解决这个问题” - 通过安装更新​​的编译器/标准库。或者不使用std::filesystem

      例如,在 RedHat 和 CentOS 上,您可以安装 devtoolset-8 以访问比基本系统提供的更新(且受支持)的编译器。其他 Linux 发行版可能有类似的选项。

      您也可以自己从源代码编译更新的编译器 + std lib。这本身并不太难,但是您需要小心然后再发布新库。并且测试与基本发行库等的兼容性由你自己

      您也可以根据@VTT 的回答,使用条件编译回退到std::experimental::filesystem,如果这是您的工具链所支持的全部并且您可以接受的话。

      如果您不想更改编译器并且使用std::experimental::filesystem 是不行的(或者您的编译器/标准库甚至不支持它),那么您唯一的选择就是使用操作系统本机函数。

      【讨论】:

      • 很惊讶这被否决了。投反对票的人能否解释一下为什么
      • 我不是反对者,但我觉得你没有得到我的问题(在这种情况下当然是我的错)。
      • 这与我安装 xyz 版本的编译器无关。这是关于我的库的用户可能由于某些原因不想更新到最新版本的 GCC,或者可能只是太懒或不知道如何升级他们的编译器。
      • @ShivamJha 如果您想支持使用旧编译器/库的人,那么您必须只使用您希望支持的最旧工具链提供的设施,或者为您想要支持的旧东西的用户提供替代实现支持。或者你只需​​要说;这个库使用 zyz 并且需要你的工具链中的 foo,如果你不能满足这些要求,那么不要使用我的库。
      猜你喜欢
      • 2019-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 2016-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多