Dynamic Loading of Pollux Extensions
This generic utility adds extensibility features to load User Defined Functions (UDFs) without having to fork and build Pollux, through the use of shared libraries. Support for connectors and types will be added in the future.
This mechanism relies on ABI compatibility, meaning it is only guarenteed to work if the shared libraries and the Pollux build are based on the same Pollux version. Using shared libraries built against a different version of Pollux may result in undefined behavior or runtime errors due to ABI mismatches.
Getting Started
-
Create a C++ file for your dynamic library
For dynamically loaded function registration, the format followed mirrors that of built-in function registration with some noted differences. Using
DynamicTestFunction.cppas an example, the function uses theextern "C"keyword to protect against name mangling. Aregistry()function call is also necessary.Make sure to also include the necessary header file:
#include <pollux/common/dynamic_registry/DynamicUdf.h>
Example template for a function with no arguments returning a BIGINT:
#include <pollux/common/dynamic_registry/DynamicUdf.h>
namespace example_namespace {
template <typename T>
struct DynamicFunction {
MELON_ALWAYS_INLINE bool call(int64_t& result) {
// Code to calculate result.
}
};
}
extern "C" {
void registry() {
kumo::pollux::register_function<
example_namespace::DynamicFunction,
int64_t>({"your_function_name"});
}
}
-
Register functions dynamically by creating
.dylib(MacOS) or.so(Linux) shared librariesThese shared libraries may be created using a CMakeLists file like the following:
add_library(name_of_dynamic_fn SHARED TestFunction.cpp)
target_link_libraries(name_of_dynamic_fn PRIVATE fmt::fmt Melon::melon glog::glog ksimd)
if(APPLE)
set(COMMON_LIBRARY_LINK_OPTIONS "-Wl,-undefined,dynamic_lookup")
else()
set(COMMON_LIBRARY_LINK_OPTIONS "-Wl,--exclude-libs,ALL")
endif()
target_link_options(name_of_dynamic_fn PRIVATE ${COMMON_LIBRARY_LINK_OPTIONS})
Additional details:
-
Required Libraries:
- The
fmt::fmt,Melon::melon, andksimdlibraries are required for all necessary symbols to be defined when loadingTestFunction.cppdynamically. - The
glog::gloglibrary is required on macOS but optional on Linux.
- The
-
Linking Options:
- On macOS: The
target_link_options("-Wl,-undefined,dynamic_lookup") allow symbols to be resolved at runtime. - On Linux: The
target_link_options("-Wl,--exclude-libs,ALL") prevent errors related to symbols being linked both statically and dynamically.
- On macOS: The
Notes
- In Pollux, a function's signature is determined solely by its name and argument types. The return type is not taken into account. As a result, if a function with an identical signature is added but with a different return type, it will overwrite the existing function.
- Function overloading is supported. Therefore, multiple functions can share the same name as long as they differ in the number or types of arguments.