Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
jazzy

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
kilted

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
lyrical

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
rolling

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro ardent showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro bouncy showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro crystal showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro eloquent showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro dashing showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro galactic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro foxy showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro iron showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro lunar showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro jade showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro indigo showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro hydro showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro kinetic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

No version for distro melodic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
humble

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange

Package symbol

boost_plugin_loader package from boost_plugin_loader repo

boost_plugin_loader

ROS Distro
noetic

Package Summary

Version 0.5.0
License Apache 2.0
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/tesseract-robotics/boost_plugin_loader.git
VCS Type git
VCS Version main
Last Updated 2026-10-30
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Boost plugin loader implementation

Maintainers

  • Levi Armstrong
  • Michael Ripperger

Authors

  • Levi Armstrong
  • Michael Ripperger

Boost Plugin Loader

Plugin loading library based on Boost DLL

codecov

Platform CI Status
Linux (Focal, Jammy, Noble) Build Status
Windows Build Status
Lint (Clang-Format) Build Status
Lint (CMake-Format) Build Status
Lint (Clang-Tidy) Build Status

Github Issues

license - apache 2.0

Usage

The plugin loader must know the names of the libraries in which to search for plugins. These library names should not contain a prefix (i.e., lib/) or suffix (i.e., .so). The library names can be set in two ways:

  1. Set the search_libraries member directly in code
  2. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_libraries_env member to the name of that environment variable.

The plugin loader must also know the paths in which to look for the specified libraries that contain plugins. These paths can also be set in three ways:

  1. Set the search_system_folders member true. This will allow the plugin loader to look for plugins in directories specified by system environment variables (e.g., LD_LIBRARY_PATH). Generally this is the easiest approach.
  2. Set the search_paths member directly in code
  3. Add a list of library names to an arbitrary environment variable (separated by colon), and set the search_paths_env member to the name of that environment variable

Defining a plugin base class

At a minimum, there are no requirements on the definition of a base class that can be used with this plugin loader. However, there is one optional requirement for enabling the plugin loader to discover the names of all plugins inheriting a specific base class type. Namely, the plugin base class must have a member function static std::string getSection() which defines a section name for the plugin and is accessible to the PluginLoader and has_getSection classes. The section name is a unique 8-byte string that associates implementations to the base class. The plugin loader method getAvailablePlugins can identify all symbols in a library with this section name and thereby return all implementations of a particular base class. It is also generally useful to define a new export macro for the base class that invokes the EXPORT_CLASS_SECTIONED macro with the section name directly. See the test plugin base class definition for an example.

Declaring plugin implementations

Creating an implementation of a plugin is as simple as inheriting from the plugin base class, and calling the EXPORT_CLASS_SECTIONED macro with the correct section (or calling a custom export macro defined for the plugin base class, described above). See the test plugin implementations for an example.

Usage Notes

Multiple instances of the same plugin with varying configuration

Objects loaded with PluginLoader<T>::createInstance are effectively singleton objects. Multiple calls to PluginLoader<T>::createInstance with the same arguments will create a pointer to the same object. If you need to load multiple instances of the same type of plugin but configured differently, consider making your plugin base class a factory that is itself capable of creating and configuring objects. See the ShapeFactory plugin for an example implementation.

Keep plugins in scope during use

Once the plugin object goes out of scope, the library providing it will be unloaded, resulting in undefined behavior and potential segfaults. Thus, the plugin object must be kept in scope for as long as it (and objects created by it) are being used. Here is an example of what not to do:

boost_plugin_loader::PluginLoader<ShapeFactory> plugin_loader;

Shape::Ptr shape;
{
  ShapeFactory::Ptr square_factory = plugin_loader.createInstance("Square");
  shape = square_factory.create(2.0);
  
  // Library providing "Square" plugin is unloaded here when `square_factory` goes out of scope
}

std::cout << "Square area: " << shape->area() << std::endl;  // <-- segfault because the library providing plugin factory (and the object generated by it) was unloaded

CHANGELOG

Changelog for package boost_plugin_loader

0.5.0 (2026-10-30)

  • Merge pull request #46 from tesseract-robotics/shared-library-cache Share cached libraries with plugin instances instead of copying them

  • CI: run macOS on macos-15; Homebrew dropped bottles for macos-14

  • Apply cmake-format

  • Potential fix for pull request finding 'Link benchmark target against Threads::Threads' Co-authored-by: Copilot Autofix powered by AI <<175728472+Copilot@users.noreply.github.com>>

  • Test createSharedInstance from a LoadedLibrary, including a missing symbol

  • Apply clang-format

  • Share cached libraries with plugin instances instead of copying them createInstance on an already-loaded library cost ~1 ms on macOS and serialised across threads (#45). Per call it copied boost::dll::shared_library (dlopen / dlclose under dyld's process-wide lock via path_from_handle), re-read and parsed the library file for its section symbols, and stat'ed every library name.

    - The cache holds one shared_ptr<shared_library> per library with its location, resolved once at load. Instances alias it; lifetime tokens share it.

    • A per-library SymbolIndex reads each section's symbols from the file once.

    - is_absolute() before exists(); a cached absolute path skips the stat. macOS arm64, 8 threads with a loader each: 1020 us -> 0.5 us per call, contention factor 8 -> ~2.5 (test/plugin_loader_concurrency_bench.cpp). createSharedInstance(shared_library, name) is unchanged. Closes #45

  • Contributors: Jelle Feringa

0.4.5 (2026-09-09)

  • Add plugin library lifetime tokens Add an explicit API for eagerly loading configured plugin libraries and returning independent RAII lifetime tokens. Each token includes the resolved library path for deduplication and retains type-erased shared ownership after the originating PluginLoader is cleared or destroyed. Add unit coverage for token acquisition and ownership persistence.
  • Cancel superseded pull-request CI runs Five workflows trigger on push, pull_request and a daily cron with no concurrency group, so every push to an open PR left the previous run building. Supersede in-progress pull-request runs only; pushes and cron runs still queue so two runs on one ref never race. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Windows v15 is the first release with Windows ccache support, so this is the only platform gaining caching it never had. The -G "Ninja" already passed in both arg sets is the precondition: the Visual Studio generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER silently, and the only symptom would be zero cacheable calls. The prefix named matrix.distro, a key this single-leg job never defined, so it expanded to the empty string. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Bump colcon-action to v15 on Linux and macOS ccache has never worked on either platform. The save step never ran, so every run was cold, and the launcher never reached the compiler: on Linux it was passed in a second --cmake-args group, which colcon drops as last-wins; on macOS [if [ ... = "true" ]]]{.title-ref} errors and forced the no-launcher branch. That same bracket also skipped rosdep install, so fixing it would newly run rosdep against a package.xml declaring libboost-filesystem-dev, which has no Homebrew mapping and nothing to install there - Boost comes from vcpkg. Disable it on macOS instead. CCACHE_DIR was load-bearing under v14, whose cache path was relative; v15 resolves the directory itself, so drop it. Co-Authored-By: Claude Opus 5 <<noreply@anthropic.com>>
  • Contributors: Levi Armstrong, Roelof Oomen

0.4.4 (2026-08-21)

  • Add BUILD_EXAMPLES option
  • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04 (#40)
    • Dropped CI support for Ubuntu 20.04; added CI support for Ubuntu 26.04
    • Bump colcon-action to v14
  • Contributors: Michael Ripperger, Rick van Essen

0.4.3 (2025-11-03)

  • Fixed finding multiple libraries during library loading
  • Contributors: David Spielman

0.4.2 (2025-10-14)

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

Name Deps
reach
tesseract

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged boost_plugin_loader at Robotics Stack Exchange