AtlatestRepositorycore-channel
core-channel / tree / src / core / packageslibc.sgl
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 at6
;;; its conventional absolute path (`/lib/ld-musl-x86_64.so.1`) only because7
;;; some DECLARED dependency ships it in its store item, and nothing else in8
;;; the namespace can supply one. That is deliberate: a loader resolved from9
;;; whatever the host happened to have is a machine-specific input that no10
;;; derivation record mentions, and the spike measured what it costs when the11
;;; guess lands badly -- a segfaulting `temacs`, with no error anywhere.12
;;;13
;;; So a package that produces a DYNAMICALLY linked musl executable must be14
;;; able to say where its loader comes from. This is that package. Depend on15
;;; it and the loader is bound; do not, and a dynamic executable fails at exec16
;;; with ENOENT rather than silently running against something unrecorded.17
;;;18
;;; MOST PACKAGES DO NOT NEED IT. `x86_64-linux-musl-cc` links STATIC by19
;;; default (measured: GNU hello built through it has no INTERP segment at all20
;;; and runs), so the whole channel builds without a loader today. This21
;;; 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 is24
;;; 1.2.5 -- `lib/libc/musl/src/internal/version.h` in the pinned toolchain25
;;; reads `#define VERSION "1.2.5"`. Pinning the same release keeps the26
;;; loader and the libc that executables were LINKED against identical rather27
;;; than merely compatible. If the toolchain is re-pinned, re-read that file28
;;; 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
(begin36
(define musl37
(package38
name: "musl"39
version: "1.2.5"40
source: (external-source41
location: "https://musl.libc.org/releases/musl-1.2.5.tar.gz"42
sha256: "a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4")43
buildenv: core-buildenv44
phases: (list45
;; WHY THIS PATCH EXISTS. musl installs46
;; `lib/ld-musl-x86_64.so.1` as a symlink to47
;; `$(libdir)/libc.so` -- an ABSOLUTE path, which here is48
;; `/sigil/store/<item>/lib/libc.so` and exists only inside49
;; the sandbox. The sandbox assembly runs on the HOST,50
;; before the chroot, so it cannot resolve that symlink and51
;; 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 time55
;; and names the dangling symlink; before P1.3 it skipped the56
;; bind silently and the failure surfaced as an ENOENT at57
;; 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-phase62
kind: 'patch63
patches: (list64
(channel-patch65
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 absolute69
;; host path OUTSIDE this package's own prefix -- the install70
;; would escape DESTDIR exactly the way ncurses' terminfo71
;; database does without its `ticdir` pin.72
(external-phase73
kind: 'configure74
args: (list "--prefix=${out}"75
"--syslibdir=${out}/lib"))76
(external-phase kind: 'make)77
(external-phase kind: 'install))))))