1 //! [![github]](https://github.com/dtolnay/linkme) [![crates-io]](https://crates.io/crates/linkme) [![docs-rs]](https://docs.rs/linkme)
2 //!
3 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6 //!
7 //! <br>
8 //!
9 //! **A library for safe cross-platform linker shenanigans.**
10 //!
11 //! <br>
12 //!
13 //! # Platform support
14 //!
15 //! | Component | Linux | macOS | Windows | FreeBSD | illumos | Other...<sup>†</sup> |
16 //! |:---|:---:|:---:|:---:|:---:|:---:|:---:|
17 //! | Distributed slice | �� | �� | �� | �� | �� | |
18 //!
19 //! <br>***<sup>†</sup>*** We welcome PRs adding support for any platforms not
20 //! listed here.
21 //!
22 //! <br>
23 //!
24 //! # Distributed slice
25 //!
26 //! A distributed slice is a collection of static elements that are gathered
27 //! into a contiguous section of the binary by the linker. Slice elements may be
28 //! defined individually from anywhere in the dependency graph of the final
29 //! binary.
30 //!
31 //! Refer to [`linkme::DistributedSlice`][DistributedSlice] for complete details
32 //! of the API. The basic idea is as follows.
33 //!
34 //! A static distributed slice is declared by writing `#[distributed_slice]` on
35 //! a static item whose type is `[T]` for some type `T`. The initializer
36 //! expression must be `[..]` to indicate that elements come from elsewhere.
37 //!
38 //! ```
39 //! # #![cfg_attr(feature = "used_linker", feature(used_with_arg))]
40 //! #
41 //! # struct Bencher;
42 //! #
43 //! use linkme::distributed_slice;
44 //!
45 //! #[distributed_slice]
46 //! pub static BENCHMARKS: [fn(&mut Bencher)] = [..];
47 //! ```
48 //!
49 //! Slice elements may be registered into a distributed slice by a
50 //! `#[distributed_slice(...)]` attribute in which the path to the distributed
51 //! slice is given in the parentheses. The initializer is required to be a const
52 //! expression.
53 //!
54 //! ```
55 //! # #![cfg_attr(feature = "used_linker", feature(used_with_arg))]
56 //! #
57 //! # mod other_crate {
58 //! #     use linkme::distributed_slice;
59 //! #
60 //! #     pub struct Bencher;
61 //! #
62 //! #     #[distributed_slice]
63 //! #     pub static BENCHMARKS: [fn(&mut Bencher)] = [..];
64 //! # }
65 //! #
66 //! # use other_crate::Bencher;
67 //! #
68 //! use linkme::distributed_slice;
69 //! use other_crate::BENCHMARKS;
70 //!
71 //! #[distributed_slice(BENCHMARKS)]
72 //! static BENCH_DESERIALIZE: fn(&mut Bencher) = bench_deserialize;
73 //!
74 //! fn bench_deserialize(b: &mut Bencher) {
75 //!     /* ... */
76 //! }
77 //! ```
78 //!
79 //! The distributed slice behaves in all ways like `&'static [T]`.
80 //!
81 //! ```no_run
82 //! # #![cfg_attr(feature = "used_linker", feature(used_with_arg))]
83 //! #
84 //! # use linkme::distributed_slice;
85 //! #
86 //! # struct Bencher;
87 //! #
88 //! # #[distributed_slice]
89 //! # static BENCHMARKS: [fn(&mut Bencher)] = [..];
90 //! #
91 //! fn main() {
92 //!     // Iterate the elements.
93 //!     for bench in BENCHMARKS {
94 //!         /* ... */
95 //!     }
96 //!
97 //!     // Index into the elements.
98 //!     let first = BENCHMARKS[0];
99 //!
100 //!     // Slice the elements.
101 //!     let except_first = &BENCHMARKS[1..];
102 //!
103 //!     // Invoke methods on the underlying slice.
104 //!     let len = BENCHMARKS.len();
105 //! }
106 //! ```
107 
108 #![no_std]
109 #![doc(html_root_url = "https://docs.rs/linkme/0.3.10")]
110 #![allow(
111     clippy::doc_markdown,
112     clippy::empty_enum,
113     clippy::expl_impl_clone_on_copy,
114     clippy::manual_assert,
115     clippy::missing_panics_doc,
116     clippy::must_use_candidate,
117     clippy::unused_self
118 )]
119 
120 // ANDROID: Use std to allow building as a dylib.
121 #[cfg(android_dylib)]
122 extern crate std;
123 
124 mod distributed_slice;
125 
126 // Not public API.
127 #[doc(hidden)]
128 #[path = "private.rs"]
129 pub mod __private;
130 
131 pub use linkme_impl::*;
132 
133 pub use crate::distributed_slice::DistributedSlice;
134