geometry2 icon indicating copy to clipboard operation
geometry2 copied to clipboard

tf2::fromMsg / tf2::toMsg can compile with undefined symbols

Open dvdmc opened this issue 7 months ago • 2 comments

Operating System:

Ubuntu 22.04

ROS version or commit hash:

Jazzy

Steps to reproduce issue

  1. Use tf2::toMsg with a geometry_msgs::msg::PoseStamped as first parameter and tf2::Transform or the oposite (Pose and tf2::Stampedtf2::Transform), which are not defined templates in tf2_geometry_msgs/tf2_geometry_msgs.hpp

Expected behavior

The compiler should complain but doesn't, probably due to the declaration of a template for tf2::fromMsg but I am missing background on this library to be sure :)

Actual behavior

The compiler doesn't complain. Got:

undefined symbol: _ZN3tf27fromMsgIN13geometry_msgs3msg10Transform_ISaIvEEEKNS_9TransformEEEvRKT_RT0_ 
[ros2run]: Process exited with failure 127 

Additional information

Maybe this is a problem with my specific compiler or system but, in case that another user experiences this issue, make sure you are using a specialized template inside tf2_geometry_msgs/tf2_geometry_msgs.hpp

dvdmc avatar May 23 '25 17:05 dvdmc

🧇 @alsora might more info

These functions are implemented as template functions. It's expected that users would include headers with template specializations for the conversions.

https://github.com/ros2/geometry2/blob/906b659ebb9d4a22cd43433bcc5a21c8da145b0d/tf2/include/tf2/convert.hpp#L122-L138

It might be worth rethinking if these are APIs even belong in the tf2 package. It seems like conversion functions for ROS types should live in tf2_ros instead. Maybe there's a different way to offer conversion functions that fails at compile time.

sloretz avatar Jun 05 '25 17:06 sloretz

Correct.

Unfortunately I stumbled on this problem several times myself. You need to make sure that the file where the explicit template specialization that you need is included.

And unfortunately, as you pointed out, compilers will not notice the problem but they app will fail to start.

The reason is that although tf2::toMsg is a template, there's not a "generic" definition for it, but only explicit specializations. You MUST include the file with the explicit specialization that you need, otherwise you'll get a linker error.

To make things more complex, you are likely dealing with a shared library (tf2 and similar). The necessary symbol is not automatically exported, and that's why you need to "include it" in your application.

It might be worth rethinking if these are APIs even belong in the tf2 package. It seems like conversion functions for ROS types should live in tf2_ros instead. Maybe there's a different way to offer conversion functions that fails at compile time.

I think that the current location is ok-ish.. Moving it somewhere else won't really change anything and in theory it allows to have also non-ros explicit instantiations.

But I definitely agree that a different implementation that fails at compile time would be a lot better! Maybe using function overloads?

alsora avatar Jun 07 '25 09:06 alsora