I have an old Mac (circa 2009) running El Capitan version 10.11.6. Apple doesn't allow further updates of its OS on my machine, but through Macports it serves as a fine development environment for non-Apple-specific software.
I'm compiling with g++ 9.2, which supports std::filesystem out of the box, and with clang 8.0, which doesn't. (Using each compiler's native standard library, in each case.) And I'm compiling with --std=c++2a.
I've noticed the llvm 9 is supposed to support std::filesystem out of the box (https://libcxx.llvm.org/docs/UsingLibcxx.html#using-filesystem), so I downloaded clang/llvm 9 through Macports. Unfortunately, I'm hitting a snag.
Minimal code to reproduce error is a simplification of the example from 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';
}
And here's the 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")
And here's the compiler's complaints:
[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 {
...
Working backward, I find this bit of code in /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)))
As far as I can determine, this #define is the ultimate cause of the above error message.
So, my questions are:
NOTE: There's a similar question involving clang/llvm downloaded through Homebrew. Unfortunately, the commentary was not helpful. [LLVM-9 clang-9 OSX]: std::filesystem::path unrecognized
I've been looking through LLVM and encountered the following 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
So I passed -D_LIBCPP_DISABLE_AVAILABILITY
to the compiler and it worked! I doubt that it's a valid solution, but it may help someone. Another option could be sticking to https://github.com/gulrak/filesystem which is basically std::filesystem
, but outside of the standard library.
Answering some of your questions:
Is this a bug with LLVM? After all, GCC doesn't introduce a dependency between std::filesystem and the OS version.
Well, it's not a bug, but yes, it's a feature of LLVM and it seems that it's made especially for Apple.
Is this a bug with Macports? Maybe they didn't use the correct flags when building?
No, it's not a bug of Macports or Homebrew.
If I were to build LLVM and Clang natively, can I work around this issue?
As you could see this availability feature is in the sources, so it seems that it doesn't matter if you build it from sources or using a package manager.
Is it an issue at all? Maybe the good folks at LLVM know something that the good folks at GCC don't.
Unfortunately, I can't state anything here, but it should've been done for a reason.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With