不能在ROS节点上使用文件系统



我正在尝试使用std::filesystem打开一个文件夹并遍历其文件,按名称排序。

我在一个非常基本的ros包中使用这个问题的代码:

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(另一个节点,pcl_pub_node,正在使用所有ros/pcl的东西)

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}
)

当启动catkin_make时,我得到这个错误:

<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())
|        

问题的根源似乎是从std访问文件系统名称空间,我是否需要将其包含在CMakeLists中?如果有,那是怎么回事?

编辑1:我也试过这个它删除了之前的错误并导致如下:

/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....

您需要在CMakeLists.txt中添加链接器标志。首先添加一个常量:

SET(GCC_COVERAGE_LINK_FLAGS "-lstdc++fs")

然后确保它被添加到链接库中:

TARGET_LINK_LIBRARIES(node
${catkin_LIBRARIES}
${GCC_COVERAGE_LINK_FLAGS}
)

最新更新