AtlatestRepositorycore-channel
1;;; The C runtime, as a package.
2;;;
3;;; WHY A LOADER PACKAGE EXISTS AT ALL (P1.3).
4;;;
5;;; Inside the build sandbox a dynamic loader is never ambient. It appears at
6;;; its conventional absolute path (`/lib/ld-musl-x86_64.so.1`) only because
7;;; some DECLARED dependency ships it in its store item, and nothing else in
8;;; the namespace can supply one. That is deliberate: a loader resolved from
9;;; whatever the host happened to have is a machine-specific input that no
10;;; derivation record mentions, and the spike measured what it costs when the
11;;; guess lands badly -- a segfaulting `temacs`, with no error anywhere.
12;;;
13;;; So a package that produces a DYNAMICALLY linked musl executable must be
14;;; able to say where its loader comes from. This is that package. Depend on
15;;; it and the loader is bound; do not, and a dynamic executable fails at exec
16;;; with ENOENT rather than silently running against something unrecorded.
17;;;
18;;; MOST PACKAGES DO NOT NEED IT. `x86_64-linux-musl-cc` links STATIC by
19;;; default (measured: GNU hello built through it has no INTERP segment at all
20;;; and runs), so the whole channel builds without a loader today. This
21;;; package is what makes the dynamic case EXPRESSIBLE rather than blocked.
22;;;
23;;; THE VERSION PIN IS MEASURED, NOT CHOSEN. zig 0.16.0's bundled musl is
24;;; 1.2.5 -- `lib/libc/musl/src/internal/version.h` in the pinned toolchain
25;;; reads `#define VERSION "1.2.5"`. Pinning the same release keeps the
26;;; loader and the libc that executables were LINKED against identical rather
27;;; than merely compatible. If the toolchain is re-pinned, re-read that file
28;;; and move this with it.
29(define-library (core packages libc)
30 (import (sigil core)
31 (core build-environments)
32 (sigil env package)
33 (sigil build external))
34 (export musl)
35 (begin
36 (define musl
37 (package
38 name: "musl"
39 version: "1.2.5"
40 source: (external-source
41 location: "https://musl.libc.org/releases/musl-1.2.5.tar.gz"
42 sha256: "a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4")
43 buildenv: core-buildenv
44 phases: (list
45 ;; WHY THIS PATCH EXISTS. musl installs
46 ;; `lib/ld-musl-x86_64.so.1` as a symlink to
47 ;; `$(libdir)/libc.so` -- an ABSOLUTE path, which here is
48 ;; `/sigil/store/<item>/lib/libc.so` and exists only inside
49 ;; the sandbox. The sandbox assembly runs on the HOST,
50 ;; before the chroot, so it cannot resolve that symlink and
51 ;; cannot bind the loader.
52 ;;
53 ;; Measured on musl 1.2.5's own Makefile rule at line 213.
54 ;; Without the patch the builder now REFUSES at assembly time
55 ;; and names the dangling symlink; before P1.3 it skipped the
56 ;; bind silently and the failure surfaced as an ENOENT at
57 ;; exec, nowhere near the cause.
58 ;;
59 ;; The patch makes the symlink RELATIVE to its own directory,
60 ;; so it resolves identically from inside and outside.
61 (external-phase
62 kind: 'patch
63 patches: (list
64 (channel-patch
65 path: "patches/musl-relative-ldso-symlink.patch"
66 sha256: "94a0cb858be6713634145d1cf0ddd7ab31f9367e915f3a276b311de9f10d59e9")))
67 ;; `--syslibdir` is what decides where `ld-musl-x86_64.so.1`
68 ;; lands. Its default is `/lib`, which would be an absolute
69 ;; host path OUTSIDE this package's own prefix -- the install
70 ;; would escape DESTDIR exactly the way ncurses' terminfo
71 ;; database does without its `ticdir` pin.
72 (external-phase
73 kind: 'configure
74 args: (list "--prefix=${out}"
75 "--syslibdir=${out}/lib"))
76 (external-phase kind: 'make)
77 (external-phase kind: 'install))))))