syscalls: Add support for musl libc.

This commit allows using Guix on a foreign distro which uses musl libc,
for example, Alpine Linux. Usage of musl libc is detected via a new
musl-libc? variable using the Guile %host-type.

Using the new musl-libc? variable, we can now implement musl-specific
quirks. The two compatibility problems I encountered in this regard are
that musl dose not export a readdir64 and statfs64 symbol. On musl,
these two functions are implemented as CPP macros that expand to
readdir/statfs. To workaround that, a case-distinction was added.

The existing linux? variable has been modified to return true if the
%host-system contains "linux-" in order to ensure it is true for both
linux-gnu as well as linux-musl host systems.

The patch has been tested on Alpine Linux and is already used for the
downstream Guix package shipped in Alpine Linux's package repository.

* guix/build/syscalls.scm (musl-libc?): New variable.
(linux?): Truth value on any linux system.
(statfs, readdir-procedure): Support musl libc.

Signed-off-by: Sören Tempel <soeren@soeren-tempel.net>
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Change-Id: Icc4101a062381240f977f4550344bde696513c52
This commit is contained in:
Sören Tempel 2023-09-17 17:21:49 +02:00 committed by Ludovic Courtès
parent 48c1a74b24
commit 54e6788267
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5

View file

@ -836,7 +836,8 @@ (define-record-type <file-system>
(define-syntax fsword ;fsword_t (define-syntax fsword ;fsword_t
(identifier-syntax long)) (identifier-syntax long))
(define linux? (string-contains %host-type "linux-gnu")) (define musl-libc? (string-contains %host-type "linux-musl"))
(define linux? (string-contains %host-type "linux-"))
(define-syntax define-statfs-flags (define-syntax define-statfs-flags
(syntax-rules (linux hurd) (syntax-rules (linux hurd)
@ -905,7 +906,7 @@ (define-c-struct %statfs ;<bits/statfs.h>
(spare (array fsword 4))) (spare (array fsword 4)))
(define statfs (define statfs
(let ((proc (syscall->procedure int "statfs64" '(* *)))) (let ((proc (syscall->procedure int (if musl-libc? "statfs" "statfs64") '(* *))))
(lambda (file) (lambda (file)
"Return a <file-system> data structure describing the file system "Return a <file-system> data structure describing the file system
mounted at FILE." mounted at FILE."
@ -1232,7 +1233,7 @@ (define closedir*
(define (readdir-procedure name-field-offset sizeof-dirent-header (define (readdir-procedure name-field-offset sizeof-dirent-header
read-dirent-header) read-dirent-header)
(let ((proc (syscall->procedure '* "readdir64" '(*)))) (let ((proc (syscall->procedure '* (if musl-libc? "readdir" "readdir64") '(*))))
(lambda* (directory #:optional (pointer->string pointer->string/utf-8)) (lambda* (directory #:optional (pointer->string pointer->string/utf-8))
(let ((ptr (proc directory))) (let ((ptr (proc directory)))
(and (not (null-pointer? ptr)) (and (not (null-pointer? ptr))