dtolnay / linkme

Safe cross-platform linker shenanigans
Apache License 2.0
646 stars 41 forks source link

Should once_cell::sync::Lazy work with linkme? #57

Closed garypen closed 1 year ago

garypen commented 1 year ago

For reasons, backwards compatibility mainly, rather than have my list of plugins be a list of function pointers, I would like them to be a list of PluginFactories and I'd like them to be created lazily. In code terms:

#[linkme::distributed_slice]
pub static PLUGINS: [Lazy<PluginFactory>] = [..];

is my list of plugins.

Each plugin registers from a macro with something like:

#[linkme::distributed_slice(PLUGINS)]
static REGISTER_PLUGIN: Lazy<PluginFactory> =
    Lazy::new(|| PluginFactory::new::<$plugin_type>($group, $name));

I then work with PLUGINS whenever I need access to my plugins. If I never access my PLUGINS, then the Lazy code is never invoked. (BTW: Lazy is nice from a performance point of view, but I'm mainly using it to workaround the limitation that the distributed slice must be const/static.)

That works fine on OS X, Linux (arm and amd), but doesn't work on windows. The code compiles and runs, but on windows none of my plugins are registered and so I get runtime errors about missing plugins.

Before I dig into this too much. Am I expecting too much of linkme and once_cell? Is this a reasonable thing to do or am I just lucky that it works on non-windows platforms and really this is just a silly thing to try?

I'm concerned that trying to finesse away the requirement for const/static via Lazy is a potential source of problems. I wonder if I'm just lucky with the initialisation order on non-windows platforms.

dtolnay commented 1 year ago

Could you check whether this works any better in linkme 0.3.6?

garypen commented 1 year ago

I just checked and that is working fine. Thanks very much for the very quick response!