• Home
  • History
  • Annotate
Name
Date
Size
#Lines
LOC

..--

patches/25-Apr-2025-2116

src/25-Apr-2025-448150

tests/25-Apr-2025-405292

.cargo-checksum.jsonD25-Apr-20252.5 KiB11

Android.bpD25-Apr-2025846 3228

Cargo.tomlD25-Apr-20251.3 KiB5545

LICENSED25-Apr-20259.5 KiB177150

LICENSE-APACHED25-Apr-20259.5 KiB177150

LICENSE-MITD25-Apr-20251,023 2421

METADATAD25-Apr-2025372 1817

MODULE_LICENSE_APACHE2D25-Apr-20250

README.mdD25-Apr-20254.6 KiB152113

cargo_embargo.jsonD25-Apr-202525 43

README.md

1## Linkme: safe cross-platform linker shenanigans
2
3[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/linkme-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/linkme)
4[<img alt="crates.io" src="https://img.shields.io/crates/v/linkme.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/linkme)
5[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-linkme-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/linkme)
6[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/linkme/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/linkme/actions?query=branch%3Amaster)
7
8| Component | Linux | macOS | Windows | FreeBSD | illumos | Other...<sup>†</sup> |
9|:---|:---:|:---:|:---:|:---:|:---:|:---:|
10| [Distributed slice] | �� | �� | �� | �� | �� | |
11
12<b><sup>†</sup></b> We welcome PRs adding support for any platforms not listed
13here.
14
15[Distributed slice]: #distributed-slice
16
17```toml
18[dependencies]
19linkme = "0.3"
20```
21
22*Supports rustc 1.62+*
23
24<br>
25
26# Distributed slice
27
28A distributed slice is a collection of static elements that are gathered into a
29contiguous section of the binary by the linker. Slice elements may be defined
30individually from anywhere in the dependency graph of the final binary.
31
32The implementation is based on `link_section` attributes and platform-specific
33linker support. It does not involve life-before-main or any other runtime
34initialization on any platform. This is a zero-cost safe abstraction that
35operates entirely during compilation and linking.
36
37### Declaration
38
39A static distributed slice is declared by writing `#[distributed_slice]` on a
40static item whose type is `[T]` for some type `T`. The initializer expression
41must be `[..]` to indicate that elements come from elsewhere.
42
43```rust
44use linkme::distributed_slice;
45
46#[distributed_slice]
47pub static BENCHMARKS: [fn(&mut Bencher)] = [..];
48```
49
50### Elements
51
52Slice elements may be registered into a distributed slice by a
53`#[distributed_slice(...)]` attribute in which the path to the distributed slice
54is given in the parentheses. The initializer is required to be a const
55expression.
56
57```rust
58use linkme::distributed_slice;
59use other_crate::BENCHMARKS;
60
61#[distributed_slice(BENCHMARKS)]
62static BENCH_DESERIALIZE: fn(&mut Bencher) = bench_deserialize;
63
64fn bench_deserialize(b: &mut Bencher) {
65    /* ... */
66}
67```
68
69Elements may be defined in the same crate that declares the distributed slice,
70or in any downstream crate. Elements across all crates linked into the final
71binary will be observed to be present in the slice at runtime.
72
73The distributed slice behaves in all ways like `&'static [T]`.
74
75```rust
76fn main() {
77    // Iterate the elements.
78    for bench in BENCHMARKS {
79        /* ... */
80    }
81
82    // Index into the elements.
83    let first = BENCHMARKS[0];
84
85    // Slice the elements.
86    let except_first = &BENCHMARKS[1..];
87
88    // Invoke methods on the underlying slice.
89    let len = BENCHMARKS.len();
90}
91```
92
93The compiler will require that the static element type matches with the element
94type of the distributed slice. If the two do not match, the program will not
95compile:
96
97```rust
98#[distributed_slice(BENCHMARKS)]
99static BENCH_WTF: usize = 999;
100```
101
102```console
103error[E0308]: mismatched types
104  --> src/distributed_slice.rs:65:19
105   |
10617 | static BENCH_WTF: usize = 999;
107   |                   ^^^^^ expected fn pointer, found `usize`
108   |
109   = note: expected fn pointer `fn(&mut other_crate::Bencher)`
110                    found type `usize`
111```
112
113### Function elements
114
115As a shorthand for the common case of distributed slices containing function
116pointers, the distributed\_slice attribute may be applied directly to a function
117definition to place a pointer to that function into a distributed slice.
118
119```rust
120use linkme::distributed_slice;
121
122#[distributed_slice]
123pub static BENCHMARKS: [fn(&mut Bencher)] = [..];
124
125// Equivalent to:
126//
127//    #[distributed_slice(BENCHMARKS)]
128//    static _: fn(&mut Bencher) = bench_deserialize;
129//
130#[distributed_slice(BENCHMARKS)]
131fn bench_deserialize(b: &mut Bencher) {
132    /* ... */
133}
134```
135
136<br>
137
138#### License
139
140<sup>
141Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
1422.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
143</sup>
144
145<br>
146
147<sub>
148Unless you explicitly state otherwise, any contribution intentionally submitted
149for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
150be dual licensed as above, without any additional terms or conditions.
151</sub>
152