27

I'm using gcc 7.2 on Ubuntu 16.04, and I need to use the new filesystem library from C++17. Even though there is indeed a library called experimental/filesystem, I can't use any of its members. For example, when I try to compile this file:

#include <iostream>
#include <string>
#include <experimental/filesystem>
using namespace std;
namespace fs = std::experimental::filesystem::v1;

int main(){
    fs::path p1 = "/usr/share/";
}

I get a compilation error which looks like this:

$ g++-7 test.cpp -std=c++17
/tmp/ccfsMnlG.o: In function `std::experimental::filesystem::v1::__cxx11::path::path<char [12], std::experimental::filesystem::v1::__cxx11::path>(char const (&) [12])':
test.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx114pathC2IA12_cS3_EERKT_[_ZNSt12experimental10filesystem2v17__cxx114pathC5IA12_cS3_EERKT_]+0x73): undefined reference to `st
d::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status

What am I doing wrong? I don't think there's anything wrong with the code, since I just copy-pasted it from a website. Am I using the wrong version of gcc? Also, why do I need <experimental/filesystem> instead of just <filesystem> in C++17? Thanks in advance.

jww
  • 97,681
  • 90
  • 411
  • 885
Willie Jeng
  • 323
  • 1
  • 4
  • 9
  • See https://gcc.gnu.org/projects/cxx-status.html – Basile Starynkevitch Feb 11 '18 at 07:35
  • I would recommend using some *external* library like [Boost](http://boost.org/) or [Poco](http://pocoproject.org/) or [Qt](http://qt.io), or more simply use POSIX calls like [syscalls(2)](http://man7.org/linux/man-pages/man2/syscalls.2.html), notably [stat(2)](http://man7.org/linux/man-pages/man2/stat.2.html)... – Basile Starynkevitch Feb 11 '18 at 07:39
  • @BasileStarynkevitch the first link you are pointing to doesn't mention anything about file system support in GCC. In fact, I get zero matches when I search for the string "file". – mallwright Jun 04 '18 at 10:29
  • This is because you need to check the page about the libstdc++, not g++ itself. It details that support for `` is scheduled to land with g++ 8: https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2017 – Maël Nison Sep 02 '18 at 10:49

4 Answers4

19

Add the flag -lstdc++fs:

$ g++-7 test.cpp -std=c++17 -lstdc++fs

gcc 7.2 supports C++17 experimental filesystem namespace only. I do not know, maybe gcc 7.3 supports std filesystem namespace already.

273K
  • 29,503
  • 10
  • 41
  • 64
  • 3
    I have gcc 7.3 on Arch Linux and I still get the linker error, even with -lstdc++fs. – petersohn Apr 25 '18 at 18:50
  • 1
    I have gcc 8.2 which is meant to support . I have tried adding the flag and the beggining of my compiler output looks like this: g++ -c -pipe -std=c++17 -lstdc++fs -g -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_DISABLE_DEPRECATED_BEFORE=0x060000 -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I.. Still all function calls are apparently undefined... Any thought? – Iron Attorney Oct 19 '18 at 19:38
  • @IronAttorney Please copy and paste the compiler error messages. – 273K Oct 21 '18 at 12:56
  • 14
    `-lstdc++fs` has to go after your .cpp files in the command-line. If using `make`, add it to your `LDLIBS` variable. – krupan Nov 27 '18 at 22:11
  • What happens if I add I compile the same program with gcc 8 though? Would it be able to access experimental/filesystem? – happy_sisyphus May 01 '19 at 22:49
  • @SashankAryal You do not need the `-lstdc++fs` flag for GCC 8, it now implements `` with the `-std=c++17` flag. – 273K May 01 '19 at 23:20
  • I know that, but my question is can Gcc 8 compile header since it has instead> – happy_sisyphus May 02 '19 at 14:36
  • @SashankAryal Sorry. No, `experimental/` prefix must be removed.As I said GCC 8 now implements . – 273K May 02 '19 at 22:23
  • But when I write library code I do not know what compiler will be used to compile it, that's what I'm saying. – happy_sisyphus May 03 '19 at 19:54
  • @SashankAryal You can use the macro GCC_VERSION, it and other are described in the GCC manual: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html – 273K May 03 '19 at 22:42
9

You can also sudo apt install g++-8 and use #include <filesystem> as cppreference described instead of #include <experimental/filesystem> in older g++ and libstdc++ version.

If I install gcc 8 in Ubuntu, will I have 2 different libstdc++ library or merely the original one get updated?

you'll probably have two even though the newer one should work as a drop-in replacement for the old one.

I notice that a libstdc++-8-dev is installed along with g++-8.

This works for me:

g++-8 -g -Wall -std=c++17 test.cpp -lstdc++fs

It seems that even with g++-8, the filesystem library is not automatically linked, you still need to provide -lstdc++fs, and -std=c++17 is also needed in language level.

Community
  • 1
  • 1
Rick
  • 7,007
  • 2
  • 49
  • 79
3

Following worked for me:

In code:

#include <filesystem>
namespace filesystem = std::filesystem;

In CMakeLists:

set (CMAKE_CXX_FLAGS "-lstdc++fs -std=c++17")

On Ubuntu 18.04 with GCC 10.

Aquarius_Girl
  • 21,790
  • 65
  • 230
  • 411
0

One not-yet-mentioned essential that eluded me for a few hours was in the default CMakeLists.txt:

target_compile_features(compare_files PUBLIC cxx_std_11)
needs to instead be:
target_compile_features(compare_files PUBLIC cxx_std_17)

MiloNC
  • 445
  • 5
  • 7