Cmake Error when trying to use message headers from other node in project
Hello,
I'm using ROS2 Humble on Ubuntu 22 for x64 and I have a package that is autogenerating header files for some custom messages I have made. I need to use those headers in another custom ros2bag package but Cmake is giving me issues when trying to include and link to the custom headers.
Package A (with autogenerated headers):
cmake_minimum_required(VERSION 3.8)
project(ads1115_ros_driver)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
include_directories(include)
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/Ads1115.msg" # Add packages that above messages depend on, in this case geometry_msgs for Sphere.msg
)
add_executable(ads1115_ros_node src/ads1115_ros_node.cpp src/ads1115_rpi.c)
ament_target_dependencies(ads1115_ros_node rclcpp std_msgs)
rosidl_get_typesupport_target(cpp_typesupport_target
${PROJECT_NAME} rosidl_typesupport_cpp
)
message("${cpp_typesupport_target}")
target_link_libraries(ads1115_ros_node "${cpp_typesupport_target}")
ament_export_dependencies(rosidl_default_runtime
std_msgs )
ament_export_targets(ads1115_ros_node HAS_LIBRARY_TARGET)
install(
TARGETS ads1115_ros_node
EXPORT ads1115_ros_node
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# comment the line when a copyright and license is added to all source files
set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# comment the line when this package is in a git repo and when
# a copyright and license is added to all source files
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
Package B which uses header generated above:
cmake_minimum_required(VERSION 3.8)
project(data_aggregator)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
#Default to C++17
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 17)
endif()
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# find dependencies)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rosbag2_cpp REQUIRED)
find_package(ads1115_ros_driver REQUIRED)
include_directories(include)
include_directories(include ../../install/ads1115_ros_driver/include/ads1115_ros_driver/)
add_executable(data_aggregator_node src/data_aggregator_node.cpp)
target_include_directories(data_aggregator_node PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
ament_target_dependencies(data_aggregator_node rclcpp std_msgs rosbag2_cpp "ads1115_ros_driver")
target_link_libraries(data_aggregator_node rosbag2_cpp::rosbag2_cpp rclcpp::rclcpp
ads1115_ros_driver::msg::Ads1115)
#rosidl_get_typesupport_target(cpp_typesupport_target ${PROJECT_NAME} "rosidl_typesupport_cpp")
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
install(TARGETS
data_aggregator_node
DESTINATION lib/${PROJECT_NAME})
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# comment the line when a copyright and license is added to all source files
set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# comment the line when this package is in a git repo and when
# a copyright and license is added to all source files
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
The beginning of the bag recorder cpp file looks like:
#include <memory>
#include "ads1115_ros_driver/msg/ads1115.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rosbag2_cpp/writer.hpp"
And the error I get is:
CMake Error at CMakeLists.txt:26 (add_executable):
Target "data_aggregator_node" links to target
"ads1115_ros_driver::msg::Ads1115" but the target was not found. Perhaps a
find_package() call is missing for an IMPORTED target, or an ALIAS target
is missing?
Please help! Thanks
Asked by cnicho35 on 2023-07-13 16:19:35 UTC
Answers
See comment above. I did not need to link to the ads node, I needed to link to the ads cpp typesupport which is generated in package A. This library is created: "install/ads1115_ros_driver/lib/libads1115_ros_driver__rosidl_typesupport_cpp.so" and it allows me to use the headers in a separate package.
Package B CMakeListst.txt changes:
include_directories(include)
include_directories(include ../../install/ads1115_ros_driver/include/ads1115_ros_driver/)
add_executable(data_aggregator_node src/data_aggregator_node.cpp)
target_include_directories(data_aggregator_node PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
ament_target_dependencies(data_aggregator_node rclcpp std_msgs rosbag2_cpp)
target_link_directories(data_aggregator_node PRIVATE ../../install/ads1115_ros_driver/lib)
target_link_libraries(data_aggregator_node rosbag2_cpp::rosbag2_cpp rclcpp::rclcpp ads1115_ros_driver__rosidl_typesupport_cpp)
Also gotta setup package.xml so it makes sure package A is complete before starting package B.
Asked by cnicho35 on 2023-07-17 12:45:13 UTC
Comments
Update: I realized that I shouldn't really have to link to the ADS node (package A) at all; I just need the headers to work.
I edited package B as follows:
The build goes for much longer before throwing an error. The new error is:
Asked by cnicho35 on 2023-07-17 12:18:44 UTC
[...] undefined reference to `rosidl_message_type_support_t const* rosidl_typesupport_cpp::get_message_type_support_handle > >()'
collect2: error: ld returned 1 exit status
Asked by cnicho35 on 2023-07-17 12:20:23 UTC