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.
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 viadlopen()
) 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 linkedclass_loader
statically. This lead to both having a separate instance ofclass_loader
that couldn't see each other. So when loading a plugin, it would register in its own copy ofclass_loader
. To the main executable it looked like the plugin wasn't exporting any classes. To fix this, we need to make sure thatclass_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 buildclass_loader
only as a shared object (viacc_binary
) and make that available to the rest of the build viacc_library
importing only that shared object assrcs
.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.