-1

Context

I initially developed a C++17 code with gcc 9.2, but had to compile it on a system that has only gcc 8.2 available.

I had the linking error:

CMakeFiles/qegg1.dir/qegg1.cpp.o: In function `std::filesystem::exists(std::filesystem::__cxx11::path const&)':
qegg1.cpp:(.text._ZNSt10filesystem6existsERKNS_7__cxx114pathE[_ZNSt10filesystem6existsERKNS_7__cxx114pathE]+0x14): undefined reference to `std::filesystem::status(std::filesystem::__cxx11::path const&)'
CMakeFiles/qegg1.dir/qegg1.cpp.o: In function `std::filesystem::__cxx11::path::path<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::filesystem::__cxx11::path>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::filesystem::__cxx11::path::format)':
qegg1.cpp:(.text._ZNSt10filesystem7__cxx114pathC2INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES1_EERKT_NS1_6formatE]+0x64): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'

Solution

The solution to this error is explained in these posts:

Following the answers in these posts (in short, gcc 8.2 needs an explicit link to filesystem), I updated my CMakeLists by linking explicitely to stdc++fs:

set(CMAKE_CXX_STANDARD 17)
# find some dependencies ...
add_executable(myprog myprog.cpp)
target_link_libraries(myprog LINK_PUBLIC ${Boost_LIBRARIES} stdc++fs)

It compile fine on my local system (gcc 9.2) and on the remote (gcc 8.2), but I don't understand why.

Question:

How compatible is this syntax with later versions of gcc and how does it compare to the solution describe here to write:

set (CMAKE_CXX_FLAGS "-lstdc++fs -std=c++17")
WaterFox
  • 850
  • 6
  • 18
  • 1
    Putting option `-l` into the variable `CMAKE_CXX_FLAGS` is never a solution: https://stackoverflow.com/questions/43136418/how-to-add-l-ell-compiler-flag-in-cmake – Tsyvarev May 24 '21 at 16:28
  • Thanks @Tsyvarev ! It confirms what i remembered from my old lectures on cmake (more or less setting flags should raise interrogations). But still, how is it that specifying the `stdc++fs` option when gcc >= 9.2 does not trigger warnings or errors ? – WaterFox May 24 '21 at 16:34
  • 1
    Previously, the filesystem part of the standard library wasn't included in `libstdc++` but was only available by explicitly linking with `libstdc++fs`. `g++` is still shipped with `libstdc++fs` so explicitly linking with it isn't a problem even for newer `g++` versions. – Ted Lyngmo May 24 '21 at 16:38
  • 1
    This is a perfect explanation, thank you ! – WaterFox May 24 '21 at 16:41
  • Can i summarize your comment in an answer so i can close the question ? :) – WaterFox May 25 '21 at 20:10
  • 1
    @ArnaudBecheler :-) Ok, done! I really wanted to be able to provide an even cleaner way of specifying the library dependency using CMake, but I couldn't find it :-( – Ted Lyngmo May 26 '21 at 16:12

1 Answers1

1

Previously, the filesystem part of the standard library wasn't included in libstdc++ but was only available by explicitly linking with libstdc++fs. g++ is still shipped with libstdc++fs so explicitly linking with it isn't a problem even for newer g++ versions.


I was hoping to find a clean way of doing find_package similar to that of when using threads

find_package(Threads REQUIRED)
target_link_libraries(application PRIVATE Threads::Threads)

but unfortunately, I only found how to do that for Boost::filesystem...

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • Awesome, thank you for your answer! On a side note, how do you justify using PRIVATE for threads and does it means that ```libstdc++fs``` should also be declared private? – WaterFox May 27 '21 at 14:49
  • 1
    @ArnaudBecheler You're welcome! I think I read [this](https://cmake.org/pipermail/cmake/2016-May/063400.html) and decided it was a good idea. I'm not that good with CMake though. – Ted Lyngmo May 27 '21 at 14:51