Ask Your Question
0

Undefined Reference in Linking Using colcon

asked 2022-05-06 16:10:49 -0500

teddybouch gravatar image

Background: I work in underwater robotics, and DCCL is a library for encoding of messages to fit within our extremely constrained message sizes based on an original protobuf format. Just for practice before applying this to one of our real messages, I'm modifying the basic publisher/subscriber from the tutorial to encode the message to DCCL before sending. It seems to do just fine with the protobuf library, but I'm getting an undefined reference error on the DCCL library, which I assuming is a linking error.

Error:

teddybouch@Norby:~/workspace/ros2_ws$ colcon build --packages-select cpp_pubsub
Starting >>> cpp_pubsub
--- stderr: cpp_pubsub                             
/usr/bin/ld: CMakeFiles/talker.dir/src/publisher_member_function.cpp.o: in function `MinimalPublisher::timer_callback()':
publisher_member_function.cpp:(.text._ZN16MinimalPublisher14timer_callbackEv[_ZN16MinimalPublisher14timer_callbackEv]+0xa2): undefined reference to `dccl::Codec::Codec(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: publisher_member_function.cpp:(.text._ZN16MinimalPublisher14timer_callbackEv[_ZN16MinimalPublisher14timer_callbackEv]+0xed): undefined reference to `testdccl::NavigationReport::NavigationReport()'
/usr/bin/ld: publisher_member_function.cpp:(.text._ZN16MinimalPublisher14timer_callbackEv[_ZN16MinimalPublisher14timer_callbackEv]+0x1d5): undefined reference to `dccl::Codec::encode(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, google::protobuf::Message const&, bool, int)'
/usr/bin/ld: publisher_member_function.cpp:(.text._ZN16MinimalPublisher14timer_callbackEv[_ZN16MinimalPublisher14timer_callbackEv]+0x3b7): undefined reference to `testdccl::NavigationReport::~NavigationReport()'
/usr/bin/ld: publisher_member_function.cpp:(.text._ZN16MinimalPublisher14timer_callbackEv[_ZN16MinimalPublisher14timer_callbackEv]+0x3c6): undefined reference to `dccl::Codec::~Codec()'
/usr/bin/ld: publisher_member_function.cpp:(.text._ZN16MinimalPublisher14timer_callbackEv[_ZN16MinimalPublisher14timer_callbackEv]+0x48b): undefined reference to `testdccl::NavigationReport::~NavigationReport()'
/usr/bin/ld: publisher_member_function.cpp:(.text._ZN16MinimalPublisher14timer_callbackEv[_ZN16MinimalPublisher14timer_callbackEv]+0x4a3): undefined reference to `dccl::Codec::~Codec()'
/usr/bin/ld: CMakeFiles/talker.dir/src/publisher_member_function.cpp.o: in function `void dccl::Codec::load<testdccl::NavigationReport>()':
publisher_member_function.cpp:(.text._ZN4dccl5Codec4loadIN8testdccl16NavigationReportEEEvv[_ZN4dccl5Codec4loadIN8testdccl16NavigationReportEEEvv]+0x11): undefined reference to `testdccl::NavigationReport::descriptor()'
/usr/bin/ld: publisher_member_function.cpp:(.text._ZN4dccl5Codec4loadIN8testdccl16NavigationReportEEEvv[_ZN4dccl5Codec4loadIN8testdccl16NavigationReportEEEvv]+0x28): undefined reference to `dccl::Codec::load(google::protobuf::Descriptor const*, int)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/talker.dir/build.make:132: talker] Error 1
make[1]: *** [CMakeFiles/Makefile2:82: CMakeFiles/talker.dir/all] Error 2
make: *** [Makefile:141: all] Error 2
---
Failed   <<< cpp_pubsub [0.97s, exited with code 2]

Summary: 0 packages finished [1.16s]
  1 package failed: cpp_pubsub
  1 package had stderr output: cpp_pubsub

Except for the addition of the proto directory and the protobuf message definition file in it, I think that the only relevant changes are in the CMakeLists.txt and publisher_member_function.cpp, which I'm including below, but if I've missed something or anyone wants all the code for some reason, the whole package is on my Dropbox here.

CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(cpp_pubsub)

# 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)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(dccl REQUIRED)
message(STATUS "Using DCCL in ${DCCL_DIR}")
find_package(Protobuf REQUIRED)

if(NOT DEFINED DCCL_INCLUDE_DIR)
  #for DCCL 3.0.3 and newer
  get_target_property(DCCL_INCLUDE_DIR dccl INTERFACE_INCLUDE_DIRECTORIES)
endif()

if(DCCL_INCLUDE_DIR)
  message ...
(more)
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2022-05-08 00:06:46 -0500

ijnek gravatar image

updated 2022-05-09 01:27:08 -0500

TLDR, these are the lines you've got to change in your CMakeLists.txt:

add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)  # Remove dccl and Protobuf
target_link_libraries(talker dccl proto)  # Link non-ament dependencies

In more detail:

There seems to be two issues in the error log you posted:

  1. Not linking against dccl correctly
  2. Not linking against your proto file correctly

and they are both related to linking, as you suspected.

In regards to not linking against dccl correctly - dccl is a pure CMake package (doesn't follow ament guidelines), and so you have to use target_link_libraries instead of ament_target_dependencies. There is no issue calling one after the other on the same target (ie. talker).

In regards to not linking against your proto file correctly - you have to use target_link_libraries to link against the target (ie. proto) you generate from the proto file in the line - add_library(proto.... Note that you already have Protobuf linked to the proto target, so if you link the talker to the proto target, you don't need to link Protobuf.

edit flag offensive delete link more

Comments

1

Thank you so much! Not only did this fix the immediate problem, but your explanation was excellent and helped me understand the context a lot better as well!

teddybouch gravatar image teddybouch  ( 2022-05-08 14:02:56 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2022-05-06 16:10:49 -0500

Seen: 92 times

Last updated: May 09