rucc_headers/lib.rs
1//! Derives a multi-version libc header tree from real installed header sets.
2//!
3//! Design: `spec/cross-compile/08-sysroots.md` section 8.3, which calls the headers the hard half of
4//! a sysroot and says why. A glibc `.so` is a few hundred kilobytes of generated stubs and nothing
5//! equivalent exists for `/usr/include`, because headers are program text that has to be the same
6//! text the target's libc was built against. Shipping a full copy per architecture per supported
7//! release is several hundred megabytes against document 13's budget, so the per version
8//! differences go inside the files as conditionals on `__GLIBC_MINOR__` and one tree serves every
9//! release. Zig's `generic-glibc` is that artifact and `ziglang/universal-headers` is the technique;
10//! document 01.2 records both, and records that the second of them has been unfinished for years.
11//!
12//! # What this is and is not
13//!
14//! It is the derivation, and nothing else. Given the headers that glibc installs for each release in
15//! the support table, it writes one tree in which every release's text can still be read out, and it
16//! checks that claim for every file before it writes anything. It does not fetch glibc, build it,
17//! install its headers or decide which releases matter. Those are the producer's job and the
18//! producer is `tamnd/rucc-cross`, for the reason section 8.3 gives: installing a libc means
19//! fetching a libc, and a compiler checkout should not download one to run its tests.
20//!
21//! It is a build tool rather than a crate of the compiler because nothing in a compilation reads it.
22//! The compiler's half of this is two lines in `rucc-sysroot`, the directory search order and
23//! `bundled_glibc_minor`, and they are there already.
24//!
25//! # The four pieces
26//!
27//! - [`norm`] cuts a header into the pieces a conditional can go between, and says what makes two
28//! copies of one header the same. They are the same when their code is the same, because glibc
29//! moves a copyright year in every file every January and that is not a version difference.
30//! - [`diff`] lines two releases of one header up.
31//! - [`merge`] writes one file out of all of them, and reads it back to check it.
32//! - [`tree`] does that for every file in every release and counts what happened.
33//!
34//! # How to run it
35//!
36//! ```text
37//! cargo run -q -p rucc-headers -- --release 2.28=<dir> --release 2.44=<dir> --out <dir>
38//! ```
39//!
40//! Each directory is the one a release's headers are under, so the one `usr/include` is in an
41//! install ends at. The releases have to be given oldest first, and there have to be at least two,
42//! because merging one release is copying it.
43
44#![doc(html_root_url = "https://docs.rs/rucc-headers/0.10.74")]
45
46pub mod cond;
47pub mod diff;
48pub mod merge;
49pub mod norm;
50pub mod tree;