ROS2: ament: Symlink error while importing a library generated on another package

asked 2020-02-10 07:16:19 -0500

TSC gravatar image

updated 2020-02-10 07:52:46 -0500

Hi,

I have already checked other posts and also the proper way of linking a library of another package in a ament workspace but I am not able to do it somehow. Here's how it looks like:

In a package, I create a library using the following on CMakeLists:

include_directories(include)

# Add frame_transforms lib
add_library(frame_transforms src/lib/frame_transforms.cpp)
ament_target_dependencies(frame_transforms Eigen3 geometry_msgs sensor_msgs)
target_link_libraries(frame_transforms Eigen3::Eigen ${geometry_msgs_LIBRARIES} ${sensor_msgs_LIBRARIES})

install(DIRECTORY include/${PROJECT_NAME}/
        DESTINATION include/${PROJECT_NAME}
)

install(TARGETS frame_transforms
        EXPORT export_frame_transforms
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib
        RUNTIME DESTINATION bin
        INCLUDES DESTINATION include
)

On a second package, I try to link an executable node using the following:

find_package(px4_ros_com REQUIRED)

include_directories(include)
# Add node executable
add_executable(system_monitor_node
  src/system_monitor_node.cpp
)

target_link_libraries(system_monitor_node px4_ros_com::frame_transforms)
ament_target_dependencies(system_monitor_node px4_ros_com)

The part of the code that requires the other lib it looks something like:

Eigen::Vector3d test = px4_ros_com::frame_transforms::ned_to_enu_local_frame(Eigen::Vector3d(1,2,3));

This results on a symlink error when using colcon build --cmake-args -DCMAKE_BUILD_TYPE=RELWITHDEBINFO --symlink-install --event-handlers console_direct+:

Starting >>> system_monitor_ros
-- Found ament_cmake: 0.7.4 (/opt/ros/dashing/share/ament_cmake/cmake)
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.6.9", minimum required is "3") 
-- Using PYTHON_EXECUTABLE: /usr/bin/python3
-- Override CMake install command with custom implementation using symlinks instead of copying resources
-- Found builtin_interfaces: 0.7.4 (/opt/ros/dashing/share/builtin_interfaces/cmake)
-- Found rosidl_adapter: 0.7.8 (/opt/ros/dashing/share/rosidl_adapter/cmake)
-- Found rosbag2: 0.1.8 (/opt/ros/dashing/share/rosbag2/cmake)
-- Found tinyxml2_vendor:  (/opt/ros/dashing/share/tinyxml2_vendor/cmake)
-- Found poco_vendor:  (/opt/ros/dashing/share/poco_vendor/cmake)
-- Setting yaml-cpp_DIR to: '/opt/ros/dashing/share/yaml_cpp_vendor/cmake/../../../opt/yaml_cpp_vendor/lib/cmake/yaml-cpp'
-- Found rclcpp: 0.7.12 (/opt/ros/dashing/share/rclcpp/cmake)
-- Found rmw_implementation_cmake: 0.7.2 (/opt/ros/dashing/share/rmw_implementation_cmake/cmake)
-- Using RMW implementation 'rmw_fastrtps_cpp' as default
-- Found rmw_fastrtps_cpp: 0.7.6 (/opt/ros/dashing/share/rmw_fastrtps_cpp/cmake)
-- Found px4_msgs: 2.0.1 (/home/nuno/PX4/px4_ros_com_ros2/install/px4_msgs/share/px4_msgs/cmake)
-- Found px4_ros_com: 0.1.0 (/home/nuno/PX4/px4_ros_com_ros2/install/px4_ros_com/share/px4_ros_com/cmake)
-- Found PythonInterp: /usr/bin/python3 (found version "3.6.9") 
-- Configuring done                                    
-- Generating done                                     
-- Build files have been written to: /home/nuno/PX4/px4_ros_com_ros2/build/system_monitor_ros
[ 50%] Built target system_monitor
[ 75%] Linking CXX executable system_monitor_node
CMakeFiles/system_monitor_node.dir/src/system_monitor_node.cpp.o: In function `OnboardComputerStatusPublisher::OnboardComputerStatusPublisher()::{lambda()#1}::operator()() const':
/home/nuno/PX4/px4_ros_com_ros2/src/system_monitor_ros/src/system_monitor_node.cpp:58: undefined reference to `Eigen::Matrix<double, 3, 1, 0, 3, 1> px4_ros_com::frame_transforms::ned_to_enu_local_frame<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::Matrix<double, 3, 1, 0, 3, 1> const&)'
collect2: error: ld returned 1 exit status
CMakeFiles/system_monitor_node.dir/build.make:158: recipe for target 'system_monitor_node' failed
make[2]: *** [system_monitor_node] Error 1
CMakeFiles/Makefile2:136: recipe for target 'CMakeFiles/system_monitor_node.dir/all' failed
make[1]: *** [CMakeFiles/system_monitor_node.dir/all] Error 2
make: *** [all] Error 2
Makefile:140: recipe for target 'all' failed

I tried different approaches to link the lib, as using a ... (more)

edit retag flag offensive close merge delete

Comments

Nit, but:

This results on a compile error

the error you show is a linker error. Not a compiler error.

gvdhoorn gravatar image gvdhoorn  ( 2020-02-10 07:35:39 -0500 )edit

@gvdhoorn I explicetely say that's a symlink error on the question title. I rephrased it on the description (a mistake, sorry). But your comment didn't help much right? :)

TSC gravatar image TSC  ( 2020-02-10 07:41:29 -0500 )edit

I'm not familiar with using double colons in cmake.

With the exports and the ament_target_dependencies it looks correct at first pass. That should link in the exported downstream libraries.

Can you run it with VERBOSE=1 so that we can see the linker arguments to verify that it's being linked in correctly? After that I would check that the symbol that you're looking for is actually in the library that's being linked.

tfoote gravatar image tfoote  ( 2020-02-10 13:50:53 -0500 )edit