Undefined Reference in Linking Using colcon
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 ...