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