Expand description
The directory layout of one target’s sysroot, and the cache key that names it.
Design: spec/cross-compile/08-sysroots.md sections 8.2 and 8.3.
§Why the directories are split the way they are
Section 8.3 is about a multiplication. Headers are naively arch x os x libc x libc-version
trees, which for glibc alone is eight architectures times six versions and several hundred
megabytes, and spec/cross-compile/13-distribution.md has a size budget that number destroys.
The fix is two splits that turn the product into a sum. The per version differences go inside
the files as #if __GLIBC_MINOR__ >= n, so one tree serves every version. The per architecture
differences stay in directories, because they are whole files rather than lines, but only for
the small part of a libc that has any: bits/ and a handful of others. Everything else is one
copy.
That is why a sysroot here has two include directories rather than one. Sysroot::arch_include
holds the files that differ by architecture and is searched first, and
Sysroot::generic_include holds the copy that every architecture shares.
A Linux target searches four directories and not two, because the kernel’s headers are a second
pair with the same split and a different owner. They are Kernel, their root is the cache
rather than a sysroot, and the order is the libc’s two and then the kernel’s two, which is the
order zig cc -E -v prints for a glibc target. linux/ and asm/ are nine megabytes of files
that are the same for every target, so one tree is shared and only asm/ is copied per
architecture.
§Why the root is a function of the tuple
spec/cross-compile/02-the-goal.md claim 5 asks for byte identical output from different hosts.
A sysroot that lands in a directory named after the host, or after the day it was built, or
after a hash of an absolute path, breaks that before anything is compiled. So the root is the
cache directory the caller chose plus the canonical spelling of the tuple, and nothing else.
The canonical spelling is the key rather than a hash of it because it is already unique, it is
already a legal directory name, and a cache a person can read is a cache a person can debug. It
carries the whole ten field model, so x86_64-linux-gnu and x86_64-linux-gnu.2.28 are
different directories, which is the point of env_version being in the tuple at all.
Structs§
- Glibc
Skew - A glibc release the bundled tree cannot serve, and the release the tree is.
- Kernel
- The kernel’s own headers, which are not the libc’s and are shared by every target that can read them.
- Sysroot
- One target’s sysroot: where its headers are, where its link inputs are, and where the record of what they are is.
Constants§
- BUNDLED_
GLIBC - The glibc our bundled header tree is derived from.
Functions§
- bundled_
glibc_ minor - The
__GLIBC_MINOR__a target gets when it is compiled against the bundled glibc tree. - can_
be_ bundled - Whether we can produce a sysroot for this target without the user fetching anything.