Conversation
…me but can then declare their own, new geometry and spatial field types that rest of barney knows nothing about
|
I feel I'd rather have: A static initialization triggering the plugin initialization, possibly using an immediately invoked lambda. Fully implicit, no symbol search, portable with our supported compilers. Those static lifetime variables are guaranteed to be initialized before barney device is created. Worth noting, static library linking might be an issue if the plugin itself does: as only used symbols will be pulled from the archive, which might leave out the initialization variable. A way to solve that it to use CMake Another approach, more explicit, is to use the fact that we know all plugins at CMake time. From there we can generate the initialization call list in a function that is called at device init time. Basically completing the The plugin then needs to advertise a name, either deduced from its folder name or, possibly using CMake |
|
Re "OBJECT" library - yes, that is correct, the plugin registration has to be OBJECT, not static; my sample(s) use that, too. Note this is only required for the one file that has the public symbol, that itself can then link to a static library; but yes, that one registry file has to be object. Re dlopen: I'm not a huge fan of dlopen, either, BUT: static initialization unfortunately is not guaranteed to happen in the right order, i've run into issues with that in the past: the problem is that the registerPlugin() function itself has to append itself to some kind of global registry, but there is no guarantee that this is already initialized. The initialization of global variables in different compiliation units of the same shared library depends on link order. The generation of a list of plugins-to-be-loaded in the cmakefile is an interesting alternative that i've also thought about, but haven't found a good way of doing it. A simply string that lists all the names is easy to generate, but isn't enough, because somebody would still have to translate strings to symbols (at which point we'd be back to dlopen/dlsym). The only way to generate true symbol names for compiler and linker would be to have cmake generate actual c++ code, and that is also somewhat daunting.... but possible, if you think that better than dlsym. |
Indeed, the usual trick is using a function local static, runtime allocated once and leaked: All accesses to the registry then goes through calling Another way maybe... C++20 enables
That's actually what I was having in mind. Something along the lines of: The plugin declare macro needs to be updated to: With the plugin code doing something like: Static initialization might be the simplest way to deal with that, no CMake infrastructure change or like, even simpler if the C++20 route can work. I like the fact that a wrongly declared plugin will fail building with the CMake based approach, but that more invasive changes. |
|
Hm. I'm didn't think that static locals are guaranteed to be initialized before globals initialization has run - I'd have naively assumed to just be implicit globals and be initialized in that same order - but it's certainly worth a try. I'll save current version and rework to try that out... we can always go back :-) |
|
Just pushed an update in which i use a local static member to provide a list of plugins that each plugin can then add itself in its globals initialization. This leaves it to linker's globals init order in which order the plugins to register themselves, but - at least if the local static members does indeed initialize on first call even if that call itself happens in globals init - the should always have a valid list to add themselves to. note i split plugin initialization into two stages: first stage (in globals init) the plugin just registers an init function, but doesn't yet register any geom/spatial types (becuase who knows what is or isn't initialized at this stage, yet). Those initfunctions then get called by BarneyGlobalState (only) when this state gets created, at which time these plugins can export their geom/spatial type(s) into a valid barneyglobalstate. |
… if there's multiple devices being created
This adds support for a plugin mechanism in which external source directories can extend barney by additional geometry and spatial field types.
The way this works:
PluginInfrastructurein barney/anari/BarneyGlobalState.h to define a 'Plugin', to be registered under a plugin-specific name (eg, 'myPlugin'). Each such plugin can then define a set of geometries and/or spatial fields it wants to support (eg 'myNewGeom').The key benefit of this way of handling plugins is that they are not additional shared libraries, and also do not require barney to be built with any whole_archive etc flags, because they can actually link to the respective barney_static_backend while the final libanari_library_barney.so is built. They are also fully included in the backend-specific build path of barney, so will automatically get built for whatever backends barney itself gets built for.