小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
编写第一个节点C++示例的时候出错
-
我按照B站中2.1.2节的视频进行一步一步的操作,在chapt2中创建CMakeLists文件,在其中添加了rclcpp的头文件及库文件后,在集成终端中通过cmake .和make 命令后提示还缺少rmw等头文件,我按照类似的方法在CMakeLists文件中用find_package()命令查找。
cmake_minimum_required(VERSION 3.8)
project(ros2_cpp)
add_executable(ros2_cpp_node ros2_cpp_node.cpp)find_package(rclcpp REQUIRED) #直接查找到对应的头文件和库文件
message(STATUS ${rclcpp_INCLUDE_DIRS})#头文件
message(STATUS ${rclcpp_LIBRARIES})#库文件及rclcpp依赖的库文件target_include_directories(ros2_cpp_node PUBLIC ${rclcpp_INCLUDE_DIRS})#头文件包含
target_link_directories(ros2_cpp_node PUBLIC ${rclcpp_LIBRARIES})#库文件链接find_package(rmw REQUIRED)
message(STATUS ${rmw_INCLUDE_DIRS})
message(STATUS ${rmw_LIBRARIES})#库文件及rclcpp依赖的库文件target_include_directories(ros2_cpp_node PUBLIC ${rmw_INCLUDE_DIRS})#头文件包含
target_link_directories(ros2_cpp_node PUBLIC ${rmw_LIBRARIES})#库文件链接find_package(rosidl_typesupport_interface REQUIRED)
message(STATUS ${rosidl_typesupport_interface_INCLUDE_DIRS})
message(STATUS ${rosidl_typesupport_interface_LIBRARIES})#库文件及rclcpp依赖的库文件target_include_directories(ros2_cpp_node PUBLIC ${rosidl_typesupport_interface_INCLUDE_DIRS})#头文件包含
target_link_directories(ros2_cpp_node PUBLIC ${rosidl_typesupport_interface_LIBRARIES})#库文件链接find_package(rcl_interfaces REQUIRED)
message(STATUS ${rcl_interfaces_INCLUDE_DIRS})
message(STATUS ${rcl_interfaces_LIBRARIES})#库文件及rclcpp依赖的库文件target_include_directories(ros2_cpp_node PUBLIC ${rcl_interfaces_INCLUDE_DIRS})#头文件包含
target_link_directories(ros2_cpp_node PUBLIC ${rcl_interfaces_LIBRARIES})#库文件链接全部添加之后cmake .命令不再报错,但是用make命令时仍然出错,具体错误如下所示:
Consolidate compiler generated dependencies of target ros2_cpp_node
[ 50%] Linking CXX executable ros2_cpp_node
/usr/bin/ld: CMakeFiles/ros2_cpp_node.dir/ros2_cpp_node.cpp.o: warning: relocation againstg_rcutils_logging_initialized' in read-only section
.text'
/usr/bin/ld: CMakeFiles/ros2_cpp_node.dir/ros2_cpp_node.cpp.o: in functionmain': ros2_cpp_node.cpp:(.text+0x39): undefined reference to
rcutils_get_default_allocator'
/usr/bin/ld: ros2_cpp_node.cpp:(.text+0x6a): undefined reference torclcpp::InitOptions::InitOptions(rcutils_allocator_s)' /usr/bin/ld: ros2_cpp_node.cpp:(.text+0x8e): undefined reference to
rclcpp::init(int, char const* const*, rclcpp::InitOptions const&, rclcpp::SignalHandlerOptions)'
/usr/bin/ld: ros2_cpp_node.cpp:(.text+0x9d): undefined reference torclcpp::InitOptions::~InitOptions()' /usr/bin/ld: ros2_cpp_node.cpp:(.text+0xbd): undefined reference to
g_rcutils_logging_initialized'
/usr/bin/ld: ros2_cpp_node.cpp:(.text+0xd1): undefined reference torcutils_logging_initialize' /usr/bin/ld: ros2_cpp_node.cpp:(.text+0x117): undefined reference to
rcutils_get_error_string'
/usr/bin/ld: ros2_cpp_node.cpp:(.text+0x138): undefined reference torcutils_get_error_string' /usr/bin/ld: ros2_cpp_node.cpp:(.text+0x17a): undefined reference to
rcutils_reset_error'
/usr/bin/ld: ros2_cpp_node.cpp:(.text+0x19e): undefined reference torclcpp::Node::get_logger() const' /usr/bin/ld: ros2_cpp_node.cpp:(.text+0x1ba): undefined reference to
rcutils_logging_logger_is_enabled_for'
/usr/bin/ld: ros2_cpp_node.cpp:(.text+0x1f3): undefined reference torclcpp::Node::get_logger() const' /usr/bin/ld: ros2_cpp_node.cpp:(.text+0x228): undefined reference to
rcutils_log'
/usr/bin/ld: ros2_cpp_node.cpp:(.text+0x25f): undefined reference torclcpp::spin(std::shared_ptr<rclcpp::Node>)' /usr/bin/ld: ros2_cpp_node.cpp:(.text+0x2ca): undefined reference to
rclcpp::shutdown(std::shared_ptrrclcpp::Context, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: ros2_cpp_node.cpp:(.text+0x33b): undefined reference torclcpp::InitOptions::~InitOptions()' /usr/bin/ld: CMakeFiles/ros2_cpp_node.dir/ros2_cpp_node.cpp.o: in function
void __gnu_cxx::new_allocatorrclcpp::Node::construct<rclcpp::Node, char const (&) [9]>(rclcpp::Node*, char const (&) [9])':
ros2_cpp_node.cpp:(.text.ZN9__gnu_cxx13new_allocatorIN6rclcpp4NodeEE9constructIS2_JRA9_KcEEEvPT_DpOT0[ZN9__gnu_cxx13new_allocatorIN6rclcpp4NodeEE9constructIS2_JRA9_KcEEEvPT_DpOT0]+0x86): undefined reference torcutils_get_default_allocator' /usr/bin/ld: ros2_cpp_node.cpp:(.text._ZN9__gnu_cxx13new_allocatorIN6rclcpp4NodeEE9constructIS2_JRA9_KcEEEvPT_DpOT0_[_ZN9__gnu_cxx13new_allocatorIN6rclcpp4NodeEE9constructIS2_JRA9_KcEEEvPT_DpOT0_]+0xb7): undefined reference to
rclcpp::NodeOptions::NodeOptions(rcutils_allocator_s)'
/usr/bin/ld: ros2_cpp_node.cpp:(.text.ZN9__gnu_cxx13new_allocatorIN6rclcpp4NodeEE9constructIS2_JRA9_KcEEEvPT_DpOT0[ZN9__gnu_cxx13new_allocatorIN6rclcpp4NodeEE9constructIS2_JRA9_KcEEEvPT_DpOT0]+0xe7): undefined reference to `rclcpp::Node::Node(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&)'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/ros2_cpp_node.dir/build.make:97:ros2_cpp_node] 错误 1
make[1]: *** [CMakeFiles/Makefile2:85:CMakeFiles/ros2_cpp_node.dir/all] 错误 2
make: *** [Makefile:101:all] 错误 2
请大佬帮忙解答,谢谢! -
从你提供的错误信息和CMakeLists.txt文件来看,主要问题出在
target_link_directories
的使用上。在CMake中,target_link_directories
用于指定链接器搜索库文件的目录,但通常我们不需要为ROS 2的库指定这个,因为ROS 2的库通常会被find_package
自动找到并配置好。你应该使用target_link_libraries
来指定需要链接的库。修正CMakeLists.txt
首先,你需要将
target_link_directories
替换为target_link_libraries
,并确保你链接了所有必要的ROS 2库。对于你的示例,你可能需要链接rclcpp
和它的依赖库。通常,find_package(rclcpp REQUIRED)
会为你设置好大部分依赖,但你可能需要显式地链接rclcpp
本身。这里是修改后的CMakeLists.txt示例:
cmake_minimum_required(VERSION 3.8) project(ros2_cpp) # 查找rclcpp等依赖 find_package(rclcpp REQUIRED) find_package(rmw REQUIRED) # 通常rclcpp已包含这些依赖,可能不需要显式查找 find_package(rosidl_typesupport_interface REQUIRED) find_package(rcl_interfaces REQUIRED) # 添加可执行文件 add_executable(ros2_cpp_node ros2_cpp_node.cpp) # 设置包含目录 target_include_directories(ros2_cpp_node PUBLIC ${rclcpp_INCLUDE_DIRS} ${rosidl_typesupport_interface_INCLUDE_DIRS} ${rcl_interfaces_INCLUDE_DIRS} ) # 链接库 target_link_libraries(ros2_cpp_node PRIVATE rclcpp::rclcpp # 如果还有其他特定库需要链接,请在这里添加 ) # 打印配置信息(可选) message(STATUS "rclcpp include dirs: ${rclcpp_INCLUDE_DIRS}") message(STATUS "rclcpp libraries: ${rclcpp_LIBRARIES}")
注意:
- 我使用了
rclcpp::rclcpp
来链接rclcpp库,这是现代CMake(特别是当库使用别名时)的推荐方式。这确保了正确链接了rclcpp的库和它的所有依赖。 - 我移除了对
rmw
和其他库的显式链接,因为它们通常作为rclcpp的依赖被自动处理。 - 我添加了
PRIVATE
关键字到target_link_libraries
中,这表明这些库是私有依赖,不会被其他链接到ros2_cpp_node
的库共享。
编译和测试
修改CMakeLists.txt后,重新运行
cmake .
和make
来编译你的项目。如果一切正常,你的ROS 2 C++节点应该能够编译成功。调试建议
- 确保你的ROS 2环境已经正确设置,并且
colcon
或ament
构建系统(取决于你使用的ROS 2版本)已经安装了所有必要的依赖。 - 如果问题依旧存在,检查你的ROS 2版本和CMakeLists.txt中的ROS 2包版本是否兼容。
- 查看ROS 2的官方文档和社区论坛,看是否有其他人遇到并解决了类似的问题。
以上为生成回答,仅供参考~
- 我使用了
-
@小伊 谢谢,是我自己粗心搞错了
-
没关系,每个人都会犯错,重要的是能够从错误中学习并继续前进。你的诚实和积极的态度非常值得肯定。如果你需要任何帮助或者有任何疑问,随时都可以提问,我会尽我所能为你解答。加油!
以上为生成回答,仅供参考~