Rosbag2 sequential reading linker error
I am attempting to crib the test case for test_rosbag2_cpp_api.cpp in rosbag2/rosbag2_tests and write my own small sequential reader that deserializes messages based on the topic name (obviously the type has to be known and in my case I know what types are coming in from my topics, and rosbag2 doesn't support topics being published with publishers pushing different types)
I get a colcon build error suggesting packages can't be found. how do I resolve this?
Thanks for any help you can provide
filter_member_function.cpp
#include <memory>
#include <string>
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/serialization.hpp"
#include "rclcpp/serialized_message.hpp"
#include "rcpputils/filesystem_helper.hpp"
#include "rcutils/time.h"
#include "rosbag2_cpp/reader.hpp"
#include "rosbag2_cpp/readers/sequential_reader.hpp"
#include "std_msgs/msg/string.hpp"
#include <iostream>
int main(int argc, char** argv)
{
using TopicMsgT = std_msgs::msg::String;
auto rosbag_directory = rcpputils::fs::path(argv[1]);
rosbag2_cpp::StorageOptions storage_options;
rosbag2_cpp::ConverterOptions converter_options;
// storage_options.uri = rosbag_directory;
storage_options.uri = argv[1];
converter_options.output_serialization_format = "cdr";
{
rosbag2_cpp::Reader reader(std::make_unique<rosbag2_cpp::readers::SequentialReader>());
// reader.open(rosbag_directory.string());
reader.open(storage_options, converter_options);
while (reader.has_next()) {
auto bag_message = reader.read_next();
std::cout<<"Found topic name " << bag_message->topic_name << std::endl;
if (bag_message->topic_name == "/topic") {
TopicMsgT extracted_test_msg;
rclcpp::Serialization<TopicMsgT> serialization;
rclcpp::SerializedMessage extracted_serialized_msg(*bag_message->serialized_data);
serialization.deserialize_message(
&extracted_serialized_msg, &extracted_test_msg);
std::cout<<"Found data in topic " << bag_message->topic_name << ": " << extracted_test_msg.data << std::endl;
}
}
// close on scope exit
}
return 0;
}
package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>cpp_rosbag2</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="noone@todo.todo">rtk2</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<depend>rosbag2_cpp</depend>
<depend>std_msgs</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
CMakelists.txt
cmake_minimum_required(VERSION 3.5)
project(cpp_rosbag2)
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rosbag2_cpp REQUIRED)
find_package(std_msgs REQUIRED)
add_executable(rosbag2-filter src/filter_member_function.cpp)
ament_target_dependencies(rosbag2-filter rclcpp std_msgs)
install(TARGETS
rosbag2-filter
DESTINATION lib/${PROJECT_NAME})
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
colcon build errors
--- stderr: cpp_rosbag2
/usr/bin/ld: CMakeFiles/rosbag2-filter.dir/src/filter_member_function.cpp.o: in function `main':
filter_member_function.cpp:(.text+0x11f): undefined reference to `rosbag2_cpp::Reader::Reader(std::unique_ptr<rosbag2_cpp::reader_interfaces::BaseReaderInterface, std::default_delete<rosbag2_cpp::reader_interfaces::BaseReaderInterface> >)'
/usr/bin/ld: filter_member_function.cpp:(.text+0x15a): undefined reference to `rosbag2_cpp::Reader::open(rosbag2_cpp::StorageOptions ...
Just to clarify: these are not "colcon errors", but plain GNU linker errors.
Colcon is really just the driver of the build process. It doesn't do anything itself other than asking other tools to actually do the build (but then in the correct order, and while making sure the build environment is correctly setup).
As 'evidence' for this: notice how
collect2
andmake
are mentioned. Those are not part of Colcon. The former is the GNU linker, the latter is GNU Make.As to the error: as you can see in the output you show,
collect2
(ie: the linker) complains it can't find various symbols. Most likely you are not linking against a required dependency.