Note that rack requires you to build back to macOS 10.9 (which has been unsupported since 2017) and a few edges of C++17 are implemented in libc rather than headers. So you have to make sure to use the rack std::filesystem and also be a bit careful with optional and variant. .has_value works on optional for instance but some other things like get_if don’t (if i recall).
(If rack moves to 10.13 one day you really just end up with the filesystem gap which ghc::filesystem covers and is already integrated with rack).
Rack has it’s own file system wrappers in ::rack::system that should be used instead of libc. The Rack wrappers handle utf8/Unicode correctly on Windows – I’m doubtful that the libc ones do – there are a number of plugins with issues for users with extended characters in their user name because of this.
std::filesystem has apis for this which ghc::filesystem (which rack uses) supports properly. in fact you can see that rack::system is implemented using ghc::filesystem!
you just need to do the namespace swap if you are porting code which doesn’t couple rack and uses the C++ standard. Most folks (surge, rack, loads of others) do a namespace fs=std::filesystem somewhere so then can swap it on older macOS and other older libc environments.
(you are correct about the libc apis of course; but std::filesystem is libc++. And also rack.hpp replaces many of the libc apis with their own version on windows; like the fopen → fopen_u8 in common.hpp so code which includes rack.hpp is even usually safe with the commonest libc apis)