A library for safe cross-platform linker shenanigans.
Component | Linux | macOS | Windows | FreeBSD | OpenBSD | illumos | Other…† |
---|---|---|---|---|---|---|---|
Distributed slice | 💚 | 💚 | 💚 | 💚 | 💚 | 💚 |
† We welcome PRs adding support for any platforms not
listed here.
A distributed slice is a collection of static elements that are gathered into a contiguous section of the binary by the linker. Slice elements may be defined individually from anywhere in the dependency graph of the final binary.
Refer to linkme::DistributedSlice
for complete details
of the API. The basic idea is as follows.
A static distributed slice is declared by writing #[distributed_slice]
on
a static item whose type is [T]
for some type T
.
use linkme::distributed_slice;
#[distributed_slice]
pub static BENCHMARKS: [fn(&mut Bencher)];
Slice elements may be registered into a distributed slice by a
#[distributed_slice(...)]
attribute in which the path to the distributed
slice is given in the parentheses. The initializer is required to be a const
expression.
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) {
/* ... */
}
The distributed slice behaves in all ways like &'static [T]
.
fn main() {
// Iterate the elements.
for bench in BENCHMARKS {
/* ... */
}
// Index into the elements.
let first = BENCHMARKS[0];
// Slice the elements.
let except_first = &BENCHMARKS[1..];
// Invoke methods on the underlying slice.
let len = BENCHMARKS.len();
}
JetBrains’s Rust IDE uses an outdated Rust parser that treats distributed slice declarations as invalid syntax, despite being supported in stable rustc for over 3.5 years. See https://youtrack.jetbrains.com/issue/RUST-12953.
If you hit this, you can work around it by adding a dummy initializer expression to the slice.
#[distributed_slice]
pub static BENCHMARKS: [fn(&mut Bencher)] = [..];
^^^^^^