ROS环境下CMake编写单元测试遇链接错误求助
Hey there! I’ve run into this exact kind of linker issue when setting up unit tests in ROS projects, so let’s break down what’s going wrong and how to fix it.
Why You’re Seeing This Error
The linker (/usr/bin/ld) can’t find libprime_tables.so or libsample1.so (or their static equivalents) because:
- These libraries aren’t being compiled from your
srcdirectory code at all. - Your CMake configuration isn’t telling the linker where to look for the libraries, or isn’t properly associating your test targets with the libraries.
- The test targets aren’t inheriting the necessary dependencies from the library builds.
Step-by-Step Solutions
Let’s walk through fixing this with proper Catkin/CMake practices:
1. Compile Your Core Code as Libraries
First, make sure the code in your src directory (the logic for prime_tables and sample1) is being compiled into reusable libraries. Open your project’s root CMakeLists.txt and add this:
# Compile prime_tables into a library (static or shared) add_library(prime_tables src/prime_tables.cpp) # Link any required ROS dependencies (e.g., roscpp) target_link_libraries(prime_tables ${catkin_LIBRARIES}) # Export include paths so tests can find your headers target_include_directories(prime_tables PUBLIC ${PROJECT_SOURCE_DIR}/include ${catkin_INCLUDE_DIRS} ) # Repeat for sample1 add_library(sample1 src/sample1.cpp) target_link_libraries(sample1 ${catkin_LIBRARIES}) target_include_directories(sample1 PUBLIC ${PROJECT_SOURCE_DIR}/include ${catkin_INCLUDE_DIRS} )
This tells CMake to build your core logic into libraries that your tests can link against.
2. Hook Up Your Tests Directory
Make sure your root CMakeLists.txt enables testing and includes the tests directory:
# Enable Catkin testing framework if(CATKIN_ENABLE_TESTING) # Add the tests subdirectory so its CMake rules are processed add_subdirectory(tests) endif()
3. Configure Tests to Link Against Your Libraries
Now open tests/CMakeLists.txt and set up your test executable to link against the libraries you just built. For example, if your test file is test_sample1.cpp:
# Create the test executable add_executable(test_sample1 test_sample1.cpp) # Link your custom libraries, ROS dependencies, and testing frameworks (like GTest) target_link_libraries(test_sample1 prime_tables sample1 ${catkin_LIBRARIES} ${GTEST_LIBRARIES} ) # Register the test with Catkin's rostest system (if using launch files) add_rostest_gtest(test_sample1 test_sample1.launch test_sample1.cpp)
The key here is explicitly listing prime_tables and sample1 in target_link_libraries—this tells the linker exactly which libraries to use.
4. Final Checks
- Source Your Workspace: After running
catkin_makeorcatkin build, don’t forget to source the devel setup file:
This ensures your system can find the compiled libraries when running tests.source ~/catkin_ws/devel/setup.bash - Avoid Old CMake Habits: Skip commands like
link_librariesorlink_directories—modern CMake (and Catkin) preferstarget_link_librariesandtarget_include_directoriesbecause they properly handle dependency inheritance.
Quick Troubleshooting
If you still get errors:
- Double-check that your
srcdirectory has the correct.cppfiles forprime_tablesandsample1. - Verify that your test code includes the headers correctly (e.g.,
#include "project1/prime_tables.h"). - Check the
catkin_ws/devel/lib/project1directory after building—you should seelibprime_tables.soandlibsample1.sothere.
内容的提问来源于stack exchange,提问作者Mat

