Undefined reference error when linking a custom library

asked 2022-10-18 14:13:49 -0500

ivandor gravatar image

Hi, I'm trying to migrate my ROS 1 libraries to ROS 2 and am having some trouble linking libraries together in Humble Hawksbill. I have a library (ds_asio), which gets used extensively in another library (ds_base), so I am trying to properly find and link it in my CMakeLists.txt. ds_base also includes some custom services that get generated as well.

I read the ament CMake documentation and this thread, but I'm still not sure what the recommended approach is as of Humble Hawksbill. It would be great if someone could give feedback on the CMake files and let me know if there's anything superfluous or I should be doing something differently. Thanks!

colcon build fails with the following error:

/usr/bin/ld: libds_base.so: undefined reference to `ds_asio::DsAsio::DsAsio()'
collect2: error: ld returned 1 exit status
gmake[2]: *** [CMakeFiles/ds_bus.dir/build.make:177: ds_bus] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:623: CMakeFiles/ds_bus.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
---
Failed   <<< ds_base [4.45s, exited with code 2]

CMakeLists.txt of package ds_base:

## Find required components
find_package(ament_cmake REQUIRED)
find_package(ds_asio REQUIRED)
find_package(rclcpp REQUIRED)
find_package(ds_core_msgs REQUIRED)


## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)

find_package(rosidl_default_generators REQUIRED)
set(srv_files
    "srv/StringCommand.srv"
    "srv/BoolCommand.srv"
)

# Generate the messages.
# Instead of calling generate_messages, use rosidl_generate_interfaces.
rosidl_generate_interfaces(${PROJECT_NAME}_msgs
    ${msg_files}
    ${srv_files}
    DEPENDENCIES builtin_interfaces std_msgs
    LIBRARY_NAME ${PROJECT_NAME}
)
ament_export_dependencies(rosidl_default_runtime)
###########
## Build ##
###########

## Specify additional locations of header files
include_directories(
  include 
  ${ds_asio_INCLUDE_DIRS}
  ${ds_core_msgs_INCLUDE_DIRS}
)

set(dep_list
  "ds_asio"
  "rclcpp"
  "rosidl_default_runtime"
  "ament_cmake"
  "ds_core_msgs"
)

## Your package locations should be listed before other locations
add_library(${PROJECT_NAME} SHARED

  include/ds_base/ds_global.h

  include/ds_base/util.h
  src/ds_base/util.cpp

  include/ds_base/ds_process.h
  src/ds_base/ds_process.cpp
  src/ds_base/ds_process_private.h
  src/ds_base/ds_process_private.cpp

  include/ds_base/ds_bus.h
  src/ds_base/ds_bus_private.h
  src/ds_base/ds_bus.cpp

  include/ds_base/ds_bus_device.h
  src/ds_base/ds_bus_device_private.h
  src/ds_base/ds_bus_device.cpp
  src/ds_base/ds_bus_device_private.cpp

  include/ds_base/sensor_base.h
  src/ds_base/sensor_base.cpp
  src/ds_base/sensor_base_private.h
)
rosidl_get_typesupport_target(cpp_typesupport_target
  ${PROJECT_NAME}_msgs "rosidl_typesupport_cpp")
#target_link_libraries(${PROJECT_NAME} "${cpp_typesupport_target}")

target_include_directories(${PROJECT_NAME} PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

ament_target_dependencies(${PROJECT_NAME} ${dep_list})
target_link_libraries(${PROJECT_NAME} "${cpp_typesupport_target}")

add_executable(ds_bus
        src/ds_bus_node.cpp)
target_link_libraries(ds_bus ${PROJECT_NAME})

install(TARGETS ${PROJECT_NAME}
      DESTINATION lib/${PROJECT_NAME}
)

CMakeLists.txt of package ds_asio (Library I'm trying to use in ds_base):

## Find required components
find_package(ament_cmake_auto REQUIRED)
ament_auto_find_build_dependencies()

find_package(rclcpp REQUIRED)
find_package(ds_core_msgs REQUIRED)

## System dependencies are found with CMake's conventions
find_package(Boost REQUIRED COMPONENTS system)
add_definitions(-DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG)

###########
## Build ##
###########

#include_directories(include)

## Declare a C++ library
add_library(${PROJECT_NAME} SHARED
  include/${PROJECT_NAME}/ds_match_functions.h

  include/${PROJECT_NAME}/ds_asio.h
  src/${PROJECT_NAME}/ds_asio.cpp

  include/${PROJECT_NAME}/ds_asio_helpers.h
  src/${PROJECT_NAME}/ds_asio_helpers.cpp

  include/${PROJECT_NAME}/ds_udp.h
  src/${PROJECT_NAME}/ds_udp.cpp

  include/${PROJECT_NAME}/ds_connection.h
  src/${PROJECT_NAME}/ds_connection.cpp

  include/${PROJECT_NAME}/ds_serial.h
  src/${PROJECT_NAME}/ds_serial.cpp

  include/${PROJECT_NAME}/ds_tcp_client.h
  src/${PROJECT_NAME}/ds_tcp_client.cpp

  include/${PROJECT_NAME}/ds_rosraw.h
  src/${PROJECT_NAME}/ds_rosraw.cpp

  include/${PROJECT_NAME}/ds_connection_factory.h
  src/${PROJECT_NAME}/ds_connection_factory.cpp

  src/${PROJECT_NAME}/ds_iosm.cpp ...
(more)
edit retag flag offensive close merge delete