在非ROS工作区编译含ROS库的CPP文件时出现未定义引用错误如何解决?
Hey there, let's break down why you're hitting these errors and how to fix them right away!
错误原因分析
First off, those undefined reference messages are linker errors, not compiler errors. You already added the header file paths in your Makefile, so the compiler can find declarations for ros::init, ros::NodeHandle, etc. The problem pops up during the linking phase: the linker can't locate the actual compiled code (library files) that implement these ROS functions and classes.
To put it simply: your Makefile tells the compiler where to find the header definitions, but it doesn't tell the linker where to find the binary libraries that hold the working code for those ROS APIs.
解决方法
方法1:使用ROS官方构建工具(推荐)
If you're working with ROS (Noetic, Melodic, etc.), the easiest and most reliable approach is to use catkin (for ROS1) or colcon (for ROS2). These tools handle dependencies, include paths, and library linking automatically, so you don't have to mess with manual Makefile tweaks.
For ROS1 with catkin:
- Ensure your
.cppfile is inside a catkin package (if you don't have one, create it withcatkin_create_pkg your_package_name roscpp std_msgs). - Move your code file to the
srcdirectory of the package. - Edit the package's
CMakeLists.txtto add these lines:# Declare your executable file add_executable(your_node_name src/your_file.cpp) # Link against the required ROS libraries target_link_libraries(your_node_name ${catkin_LIBRARIES}) - Run
catkin_makeorcatkin buildfrom your catkin workspace root. This will handle all the linking work behind the scenes.
方法2:手动修改Makefile(适合简单测试场景)
If you really want to stick with a custom Makefile, you need to explicitly tell it to link against the necessary ROS libraries. You can use pkg-config to automatically fetch the correct compiler and linker flags.
Here's a working example Makefile:
# Fetch ROS compile flags and library links automatically ROS_CFLAGS := $(shell pkg-config --cflags roscpp std_msgs) ROS_LIBS := $(shell pkg-config --libs roscpp std_msgs) # Name your output executable TARGET := your_custom_executable # Compile command $(TARGET): your_file.cpp g++ $^ -o $@ $(ROS_CFLAGS) $(ROS_LIBS) # Clean up built files clean: rm -f $(TARGET)
The pkg-config --cflags command grabs all required include paths, while pkg-config --libs pulls in the library links (like -lroscpp -lstd_msgs) along with their file paths. This ensures the linker can find the ROS libraries that contain the implementation for those previously undefined functions.
验证
After updating your build setup, recompile your code. The undefined reference errors should disappear once the linker can locate and link the required ROS libraries.
内容的提问来源于stack exchange,提问作者rama

