linkme
linkme copied to clipboard
Doesn't add elements to distributed slice from external crate on macOS
use linkme::distributed_slice;
use other_crate::BENCHMARKS;
#[distributed_slice(BENCHMARKS)]
static BENCH_DESERIALIZE: fn(&mut Bencher) = bench_deserialize;
fn bench_deserialize(b: &mut Bencher) {
/* ... */
}
If BENCHMARKS is initialized in external crate the call to #[distributed_slice(BENCHMARKS)] doesn't add bench_deserialize function to the array. But if I turn on lto=true in Cargo.toml of the builded project (where BENCHMARKS is placed) lib works as expected.
I also tested this on ubuntu and it worked without lto
May be the compiler is optimizing out the crate where #[distributed_slice(BENCHMARKS)] is called? Because I don't have explicit use of the crate (only through linkme::distributed_slice). This crate is added to dependecies in the other_crate by the way.
I ran into the issue in macOS, where BENCHMARKS is initialized in an external crate and the call to#[distributed_slice(BENCHMARKS)] isn't appending the array.
I tried the lto=true mentioned by @vikulikov above and that worked. lto=thin also worked.
This seems to be related to the embed-bitcode flag, which seems to be set by cargo when lto is not "off" on macOS. There's no direct way to enable this flag via cargo, so this seems to be the only workaround for now. I added this for dev builds
[profile.dev]
# Need this for linkme crate to work
lto = "thin"
Neither of the above solutions worked for me using Linux. Adding so that it's apparent that that's not a guaranteed fix.
The workaround of setting lto = true or lto = "thin" only works for me if I also add extern crate ... to the crate using the distributed_slice