【问题标题】:Does llvm 9 support std::filesystem on versions of the mac prior to 10.15?llvm 9 在 10.15 之前的 mac 版本上是否支持 std::filesystem?
【发布时间】:2019-10-31 17:13:27
【问题描述】:

我有一台运行 El Capitan 版本 10.11.6 的旧 Mac(大约 2009 年)。 Apple 不允许在我的机器上进一步更新其操作系统,但通过 Macports,它可以作为非 Apple 特定软件的良好开发环境。

我正在使用 g++ 9.2 编译,它支持开箱即用的 std::filesystem,而使用 clang 8.0,它不支持。 (在每种情况下都使用每个编译器的本机标准库。)我正在使用 --std=c++2a 进行编译。

我注意到 llvm 9 应该支持开箱即用的 std::filesystem (https://libcxx.llvm.org/docs/UsingLibcxx.html#using-filesystem),所以我通过 Macports 下载了 clang/llvm 9。不幸的是,我遇到了障碍。

重现错误的最少代码是来自 cppreference.com (https://en.cppreference.com/w/cpp/filesystem/path/path) 的示例的简化

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int
main()
{
   fs::path p1 = "/usr/lib/sendmail.cf";

   std::cout << "p1 = " << p1 << '\n';
}

这里是 CmakeLists.txt

cmake_minimum_required(VERSION 3.15.5)
project(bug LANGUAGES CXX)
add_executable (bug main.cpp)
target_compile_options(bug PRIVATE "-std=c++2a")

这是编译器的抱怨:

[build] Starting build
[proc] Executing command: /opt/local/bin/cmake --build ~/temp/build/debug/clang --config debug --target all -- -j 10
[build] [1/2  50% :: 1.598] Building CXX object CMakeFiles/bug.dir/main.cpp.o
[build] FAILED: CMakeFiles/bug.dir/main.cpp.o 
[build] /opt/local/bin/clang++    -g   -std=c++2a -MD -MT CMakeFiles/bug.dir/main.cpp.o -MF CMakeFiles/bug.dir/main.cpp.o.d -o CMakeFiles/bug.dir/main.cpp.o -c ../../../main.cpp
[build] ../../../main.cpp:9:8: error: 'path' is unavailable: introduced in macOS 10.15
[build]    fs::path p1 = "/usr/lib/sendmail.cf";
[build]        ^
[build] /opt/local/libexec/llvm-9.0/bin/../include/c++/v1/filesystem:738:24: note: 'path' has been explicitly marked unavailable here
[build] class _LIBCPP_TYPE_VIS path {
...

向后工作,我在 /opt/local/libexec/llvm-9.0/include/c++/v1/__config 中找到了这段代码:

#  define _LIBCPP_AVAILABILITY_FILESYSTEM                                      \
     __attribute__((availability(macosx,strict,introduced=10.15)))             \
     __attribute__((availability(ios,strict,introduced=13.0)))                 \
     __attribute__((availability(tvos,strict,introduced=13.0)))                \
     __attribute__((availability(watchos,strict,introduced=6.0)))

据我所知,这个#define 是上述错误信息的最终原因。

所以,我的问题是:

  • 这是 LLVM 的错误吗?毕竟,GCC 并没有在 std::filesystem 和操作系统版本之间引入依赖关系。
  • 这是 Macports 的错误吗?也许他们在构建时没有使用正确的标志?
  • 如果我要本地构建 LLVM 和 Clang,我可以解决这个问题吗?
  • 这是一个问题吗?也许 LLVM 的好人知道 GCC 的好人不知道的事情。

注意:有一个类似的问题涉及通过 Homebrew 下载的 clang/llvm。不幸的是,评论没有帮助。 [LLVM-9 clang-9 OSX]: std::filesystem::path unrecognized

【问题讨论】:

    标签: c++ gcc clang llvm std-filesystem


    【解决方案1】:

    我一直在浏览 LLVM,遇到了以下lines:

    // Decide whether to use availability macros.
    #if !defined(_LIBCPP_BUILDING_LIBRARY) &&                                      \
        !defined(_LIBCPP_DISABLE_AVAILABILITY) &&                                  \
        __has_feature(attribute_availability_with_strict) &&                       \
        __has_feature(attribute_availability_in_templates)
    #  ifdef __APPLE__
    #    define _LIBCPP_USE_AVAILABILITY_APPLE
    #  endif
    #endif
    

    所以我将-D_LIBCPP_DISABLE_AVAILABILITY 传递给编译器,它成功了!我怀疑这是一个有效的解决方案,但它可能对某人有所帮助。另一种选择可能是坚持使用https://github.com/gulrak/filesystem,它基本上是std::filesystem,但在标准库之外。

    回答您的一些问题:

    这是 LLVM 的错误吗?毕竟,GCC 并没有在 std::filesystem 和操作系统版本之间引入依赖关系。

    嗯,这不是错误,但是是的,它是 LLVM 的一个功能,而且它似乎是专为 Apple 设计的。

    这是 Macports 的错误吗?也许他们在构建时没有使用正确的标志?

    不,这不是 Macports 或 Homebrew 的错误。

    如果我要本地构建 LLVM 和 Clang,我可以解决这个问题吗?

    您可以在源代码中看到此可用性功能,因此无论您是从源代码构建它还是使用包管理器构建它似乎都没有关系。

    这是一个问题吗?也许 LLVM 的好人知道 GCC 的好人不知道的事情。

    很遗憾,我不能在这里说明任何事情,但我应该这样做是有原因的。

    【讨论】:

    • 感谢您的回答,这加强了我的发现。我最终实现了 std::filesystem (仅限 POSIX),而就在几周前,我遇到了 gulrak 的工作。我计划保留我的实施,并可能随着时间的推移对其进行优化。
    猜你喜欢
    • 1970-01-01
    • 2020-12-06
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    相关资源
    最近更新 更多