I'm following this tutorial:
http://www.bfilipek.com/2017/08/cpp17-details-filesystem.html
to checkout new c++ filesystem
feature. However I'm unable to compile even minimal example on my machine:
#include <string> #include <iostream> #include <filesystem> namespace fs = std::filesystem; int main() { std::string path = "/"; for (auto & p : fs::directory_iterator(path)) std::cout << p << std::endl; }
I was using XCode, CLion and command line while trying to compile it but nothing works, I have Version 9.3 (9E145) with (seemingly proper) project settings, none of which work:
Here is my CMakeLists.txt
file for CLion:
cmake_minimum_required(VERSION 3.8) project(FileSystem2) set(CMAKE_CXX_STANDARD 17) add_executable(FileSystem2 main.cpp)
Here is an output from > gxx --version
:
Nevertheless this is what I get as an output from my IDEs:
What am I doing wrong, it looks to me that my compiler should support c++17?
Edit
As per Owen Morgan's answer I've installed clang (actual install command was brew install llvm
) but it now complains about absence of string.h
. Any thoughts?
The compiler shipped with Xcode supports C++17 language features but not C++17 standard library features. Looking at your screenshot you will see the standard library support goes up to C++11, and Apple has not yet shipped a version of clang that has stdlib support for either C++14 or C++17.
However hope is not lost! You can download the newest version of clang from the brew package manager.
brew install clang
Then you can compile by setting your cmake compiler flags to be your custom brew version and then running that.
Here is a link how to do that: http://antonmenshov.com/2017/09/09/clang-openmp-setup-in-xcode/
Edit:
After installing llvm
you will need to link your llvm path into your current shell. I have a shell script that I use at work to get this set up properly. Hope this helps.
#!/bin/bash brew update brew install --with-toolchain llvm # llvm but with all the headers xcode-select --install # installs additional headers that you might be mimssing. echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.bash_profile # exports the custom llvm path into the shell sudo ln -s /usr/local/opt/llvm/bin/clang++ /usr/local/bin/clang++-brew # optional but I like to have a symlink set.
Edit 2:
Clang 6.0 doesn't have <filesystem>
included on macOS yet, however you can get <experimental/filesystem>
, and link against -lc++experimental
, and use std::experimental::filesystem
instead of std::filesystem
.
Final command line invocation:
Owen$ /usr/local/Cellar/llvm/6.0.0/bin/clang++ fs.cpp -std=c++1z -L /usr/local/Cellar/llvm/6.0.0/lib/ -lc++experimental
Edit 3:
Current clang version 7.0.1 supports either <filesystem>
or <experimental/filesystem>
. In any case, the compiler command line must be slightly different:
Owen$ /usr/local/Cellar/llvm/7.0.1/bin/clang++ main.cpp -std=c++1z -L /usr/local/Cellar/llvm/7.0.1/lib/ -lc++fs
with -lc++fs
instead of -lc++experimental
. Optionally, you can replace-std=c++1z
with -std=c++17
as well.
If you don't want to change compiler to use std::filesystem (because it's a pain), another option is to use the Boost Filesystem library. Boost Filesystem was the basis for std::filesystem, so for most uses it's completely compatible with std::filesystem.
Setting up Boost is pretty easy if you're using CMake. Just brew install boost
then in your CMakeLists.txt do something like:
# Boost set(boost_min_ver 1.50.0) set(boost_libs system filesystem) find_package(Boost ${boost_min_ver}) if(Boost_FOUND) find_package(Boost ${boost_min_ver} COMPONENTS ${boost_libs}) endif() target_link_libraries(your_target ${Boost_LIBRARIES})
The extra verbosity in finding Boost helps, I find, to suppress some warnings CMake would otherwise throw at you.
Then in your C++ code:
#include <boost/filesystem.hpp> namespace fs = boost::filesystem;
If you're feeling very fancy, you can use the __has_include
define to check if the standard filesystem include is available, and if so, set namespace fs = std::filesystem
and fallback to Boost only if the std version isn't available.
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