0

I'm trying to use std::filesystem to open a folder and iterate through its files, sorted by name.

I'm using the code from this question inside a very basic ros package:

node.cpp

#include <ros/ros.h>

#include <fstream>
#include <string>
#include <iostream>
#include <filesystem>
#include <set>


int main(int argc, char **argv)
{

    string path_name = "/bin";

    //--- filenames are unique so we can use a set
    set<fs::path> sorted_by_name;

    for (auto &entry : fs::directory_iterator(path_name))
    {
        sorted_by_name.insert(entry.path())
    }
    

    return 0;
}

CMakeLists.txt (the other node, pcl_pub_node, is using all the ros/pcl stuff)

cmake_minimum_required(VERSION 3.0.2)
project(mapping_utilities)

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  pcl_ros
  sensor_msgs
  std_msgs
  tf
  tf2
  submap_matching_msgs
  eigen_conversions
)

catkin_package(
  INCLUDE_DIRS include
  CATKIN_DEPENDS geometry_msgs pcl_ros sensor_msgs std_msgs tf submap_matching_msgs

)

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

find_package(PCL REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})

add_executable (pcl_pub_node src/pcl_pub_node.cpp)

TARGET_LINK_LIBRARIES(pcl_pub_node
    ${catkin_LIBRARIES}
)

add_executable (node src/node.cpp)

TARGET_LINK_LIBRARIES(node
    ${catkin_LIBRARIES}
)

When launching catkin_make I get this error:

<path>/node.cpp: error: ‘filesystem’ is not a namespace-name
   23 | namespace fs = std::filesystem;
      |                     ^~~~~~~~~~
/<path>/node.cpp: In function ‘int main(int, char**)’:
/<path>/node.cpp:38:9: error: ‘fs’ was not declared in this scope; did you mean ‘ffs’?
   38 |     set<fs::path> sorted_by_name;
      |         ^~
      |         ffs
/<path>/node.cpp:38:17: error: template argument 1 is invalid
   38 |     set<fs::path> sorted_by_name;
      |                 ^
/<path>/node.cpp:38:17: error: template argument 2 is invalid
/<path>/node.cpp:38:17: error: template argument 3 is invalid
/<path>/node.cpp:40:24: error: ‘fs’ is not a class, namespace, or enumeration
   40 |     for (auto &entry : fs::directory_iterator(path_name))
      |                        ^~
/<path>/node.cpp:42:24: error: request for member ‘insert’ in ‘sorted_by_name’, which is of non-class type ‘int’
   42 |         sorted_by_name.insert(entry.path())
      |        

The root of the problem seems to be accessing the fylesistem namespace from std, do I need to include it in the CMakeLists as well? If so how?

EDIT 1: I also tried this it removed the previous error and cause this:

/usr/bin/ld: CMakeFiles/MAG_dataset_script.dir/src/MAG_dataset_script.cpp.o: in function `std::pair<std::_Rb_tree_iterator<std::experimental::filesystem::v1::__cxx11::path>, bool> std::_Rb_tree<std::experimental::filesystem::v1::__cxx11::path, std::experimental::filesystem::v1::__cxx11::path, std::_Identity<std::experimental::filesystem::v1::__cxx11::path>, std::less<std::experimental::filesystem::v1::__cxx11::path>, std::allocator<std::experimental::filesystem::v1::__cxx11::path> >::_M_insert_unique<std::experimental::filesystem::v1::__cxx11::path const&>(std::experimental::filesystem::v1::__cxx11::path const&)':
MAG_dataset_script.cpp:(.text._ZNSt8_Rb_treeINSt12experimental10filesystem2v17__cxx114pathES4_St9_IdentityIS4_ESt4lessIS4_ESaIS4_EE16_M_insert_uniqueIRKS4_EESt4pairISt17_Rb_tree_iteratorIS4_EbEOT_[_ZNSt8_Rb_treeINSt12experimental10filesystem2v17__cxx114pathES4_St9_IdentityIS4_ESt4lessIS4_ESaIS4_EE16_M_insert_uniqueIRKS4_EESt4pairISt17_Rb_tree_iteratorIS4_EbEOT_]+0x5b): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::compare(std::experimental::filesystem::v1::__cxx11::path const&) const'
/usr/bin/ld: MAG_dataset_script.cpp:(.text._ZNSt8_Rb_treeINSt12experimental10filesystem2v17__cxx114pathES4_St9_IdentityIS4_ESt4lessIS4_ESaIS4_EE16_M_insert_uniqueIRKS4_EESt4pairISt17_Rb_tree_iteratorIS4_EbEOT_[_ZNSt8_Rb_treeINSt12experimental10filesystem2v17__cxx114pathES4_St9_IdentityIS4_ESt4lessIS4_ESaIS4_EE16_M_insert_uniqueIRKS4_EESt4pairISt17_Rb_tree_iteratorIS4_EbEOT_]+0x93): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::compare(std::experimental::filesystem::v1::__cxx11::path const&) const'
/usr/bin/ld: MAG_dataset_script.cpp:(.text._ZNSt8_Rb_treeINSt12experimental10filesystem2v17__cxx114pathES4_St9_IdentityIS4_ESt4lessIS4_ESaIS4_EE16_M_insert_uniqueIRKS4_EESt4pairISt17_Rb_tree_iteratorIS4_EbEOT_[_ZNSt8_Rb_treeINSt12experimental10filesystem2v17__cxx114pathES4_St9_IdentityIS4_ESt4lessIS4_ESaIS4_EE16_M_insert_uniqueIRKS4_EESt4pairISt17_Rb_tree_iteratorIS4_EbEOT_]+0x252): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::compare(std::experimental::filesystem::v1::__cxx11::path const&) const'
/usr/bin/ld: MAG_dataset_script.cpp:(.text._ZNSt8_Rb_treeINSt12experimental10filesystem2v17__cxx114pathES4_St9_IdentityIS4_ESt4lessIS4_ESaIS4_EE16_M_insert_uniqueIRKS4_EESt4pairISt17_Rb_tree_iteratorIS4_EbEOT_[_ZNSt8_Rb_treeINSt12experimental10filesystem2v17__cxx114pathES4_St9_IdentityIS4_ESt4lessIS4_ESaIS4_EE16_M_insert_uniqueIRKS4_EESt4pairISt17_Rb_tree_iteratorIS4_EbEOT_]+0x2d1): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::compare(std::experimental::filesystem::v1::__cxx11::path const&) const'
/usr/bin/ld: CMakeFiles/MAG_dataset_script.dir/src/MAG_dataset_script.cpp.o: in function `main':
MAG_dataset_script.cpp:(.text.startup+0x1df): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
/usr/bin/ld: MAG_dataset_script.cpp:(.text.startup+0x1fc): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experimental::filesystem::v1::__cxx11::path const&, std::experimental::filesystem::v1::directory_options, std::error_code*)'
/usr/bin/ld: MAG_dataset_script.cpp:(.text.startup+0x261): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator*() const'
/usr/bin/ld: MAG_dataset_script.cpp:(.text.startup+0x274): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator++()'
collect2: error: ld returned 1 exit status
make[2]: *** [cmap/mapping_utilities/CMakeFiles/MAG_dataset_script.dir/build.make:202: /home/matteo/ROS1/local/noetic/catkin_ws/devel/lib/mapping_utilities/MAG_dataset_script] Error 1
make[1]: *** [CMakeFiles/Makefile2:10559: cmap/mapping_utilities/CMakeFiles/MAG_dataset_script.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
rebubi
  • 11
  • 1
  • 3
  • Does this answer your question? [c++17 \`filesystem\` is not a namespace-name](https://stackoverflow.com/questions/48312460/c17-filesystem-is-not-a-namespace-name) – Fruchtzwerg Sep 21 '21 at 08:50
  • answered in EDIT 1, long story short: no it caused a different error – rebubi Sep 21 '21 at 14:22

1 Answers1

0

You need to add a linker flag within your CMakeLists.txt. First add a constant:

SET(GCC_COVERAGE_LINK_FLAGS "-lstdc++fs")

Then make sure it gets added to the link libraries:

TARGET_LINK_LIBRARIES(node
    ${catkin_LIBRARIES}
    ${GCC_COVERAGE_LINK_FLAGS}
)
BTables
  • 4,413
  • 2
  • 11
  • 30