mvukov / rules_ros2

Build ROS 2 with Bazel
Apache License 2.0
85 stars 47 forks source link

Fix plugin registration with clang build #93

Closed ahans closed 1 year ago

ahans commented 1 year ago

class_loader has a couple of functions that return static variables to manage global state. Most importantly, they are used by plugins (shared objects loaded via dlopen()) to register themselves upon load. By default, code living in a shared object cannot access symbols from the main executable that loaded it. In rules_ros2, both main executables as well as plugins linked class_loader statically. This lead to both having a separate instance of class_loader that couldn't see each other. So when loading a plugin, it would register in its own copy of class_loader. To the main executable it looked like the plugin wasn't exporting any classes. To fix this, we need to make sure that class_loader is also loaded as a shared object. Then the same instance is used from a main executable as well as other shared objects (i.e., plugins). We achieve this by using some Bazel trick where we build class_loader only as a shared object (via cc_binary) and make that available to the rest of the build via cc_library importing only that shared object as srcs.

It is unclear how this was working with gcc before. It looks like the class_loader patch that pulled the local static variables into some single instance of a singleton class allowed using some gcc-specific quirk (or bug?). Always dynamically linking class_loader makes the clang build work and allows us to drop the patch.

Fixes #78.