Skip to content

Commit e055c61

Browse files
committed
build(guix): add aarch64-unknown-linux-gnu cross-compilation
Adds a new supported target triple, cross-compiled from x86_64 Linux using Guix's old-glibc toolchain machinery (same approach as the existing x86_64-linux-gnu build): * manifest.scm: aarch64-linux-gnu-toolchain built via make-ckb-cross-toolchain (glibc 2.31); openssl-aarch64-glibc-2.31 cross-compiled against that toolchain; the host-dependent branch now selects x86_64 or aarch64 packages based on the target, and aarch64 pulls in a Rust sysroot via make-rust-sysroot/implementation (rustc only ships libstd for the build host). * guix-build: aarch64-unknown-linux-gnu added to SUPPORTED_HOSTS and mapped to the aarch64-linux-gnu GNU triple. * libexec/build.sh: new HOST case with DYNAMIC_LINKER=/lib/ld-linux-aarch64.so.1 and the right TARGET_ENV_SUFFIX. Because cross-arch cross-compile differs from the existing same-arch glibc-downgrade, build scripts (build.rs, proc-macros) get CC_x86_64_unknown_linux_gnu/HOST_CC pointed at native gcc, and AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_{INCLUDE,LIB}_DIR is set directly so openssl-sys doesn't try to use the host pkg-config for a differing target arch. Hardcoded x86_64 interpreter in the patchelf call replaced with ${DYNAMIC_LINKER}. * symbol-check.py: recognise AARCH64 for the glibc 2.31 cap, the expected interpreter, and the ld-linux-aarch64.so.1 allow-list entry. Verified reproducible: x86_64-unknown-linux-gnu: 3c7d003ca216fbb31173e0da5d965f472243ef4f8b6e1288d37e6053eb566d2d aarch64-unknown-linux-gnu: 37b1b69faa879ab0f00188c51ab156df0f011912550708a5e400677c30443633 x86_64 hash is identical with and without this commit applied.
1 parent d51d9b3 commit e055c61

4 files changed

Lines changed: 99 additions & 7 deletions

File tree

contrib/guix/guix-build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ EOF
8989
}
9090

9191
HOSTS="${HOSTS:-x86_64-unknown-linux-gnu}"
92-
SUPPORTED_HOSTS="x86_64-unknown-linux-gnu x86_64-pc-windows-gnu aarch64-apple-darwin"
92+
SUPPORTED_HOSTS="x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu x86_64-pc-windows-gnu aarch64-apple-darwin"
9393
for host in $HOSTS; do
9494
if ! echo "$SUPPORTED_HOSTS" | grep -qw "$host"; then
9595
echo "ERR: Unsupported HOST '$host'. Supported: $SUPPORTED_HOSTS" >&2
@@ -179,6 +179,7 @@ for HOST in $HOSTS; do
179179
# Map Rust target triples to GNU triples for the Guix manifest.
180180
case "$HOST" in
181181
x86_64-unknown-linux-gnu) MANIFEST_HOST="x86_64-linux-gnu" ;;
182+
aarch64-unknown-linux-gnu) MANIFEST_HOST="aarch64-linux-gnu" ;;
182183
x86_64-pc-windows-gnu) MANIFEST_HOST="x86_64-w64-mingw32" ;;
183184
*) MANIFEST_HOST="$HOST" ;;
184185
esac

contrib/guix/libexec/build.sh

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ case "$HOST" in
9191
DYNAMIC_LINKER="/lib64/ld-linux-x86-64.so.2"
9292
TARGET_ENV_SUFFIX="X86_64_UNKNOWN_LINUX_GNU"
9393
;;
94+
aarch64-linux-gnu)
95+
GNU_HOST="aarch64-linux-gnu"
96+
DYNAMIC_LINKER="/lib/ld-linux-aarch64.so.1"
97+
TARGET_ENV_SUFFIX="AARCH64_UNKNOWN_LINUX_GNU"
98+
;;
9499
x86_64-w64-mingw32)
95100
GNU_HOST="x86_64-w64-mingw32"
96101
DYNAMIC_LINKER=""
@@ -338,6 +343,23 @@ HOSTCXXEOF
338343
export AR_x86_64_unknown_linux_gnu="${NATIVE_GCC}/bin/gcc-ar"
339344
export RANLIB_x86_64_unknown_linux_gnu="${NATIVE_GCC}/bin/gcc-ranlib"
340345
;;
346+
aarch64-linux-gnu)
347+
# Cross-compiling from x86_64 to aarch64: CC has been set to the
348+
# aarch64 cross-wrapper, but build scripts (build.rs, proc-macros)
349+
# still run on the x86_64 build host and must produce native x86_64
350+
# objects. Point the HOST-side CC at the native gcc.
351+
export CC_x86_64_unknown_linux_gnu="${NATIVE_GCC}/bin/gcc"
352+
export CXX_x86_64_unknown_linux_gnu="${NATIVE_GCC}/bin/g++"
353+
export AR_x86_64_unknown_linux_gnu="${NATIVE_GCC}/bin/gcc-ar"
354+
export RANLIB_x86_64_unknown_linux_gnu="${NATIVE_GCC}/bin/gcc-ranlib"
355+
export HOST_CC="${NATIVE_GCC}/bin/gcc"
356+
export HOST_CXX="${NATIVE_GCC}/bin/g++"
357+
# openssl-sys's host pkg-config would refuse to return paths when
358+
# target arch differs from host arch. Point it directly at the
359+
# aarch64 openssl in the Guix profile via target-specific env vars.
360+
export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_INCLUDE_DIR="${GUIX_ENVIRONMENT}/include"
361+
export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR="${GUIX_ENVIRONMENT}/lib"
362+
;;
341363
*darwin*)
342364
# Darwin CC wrapper uses Clang with Apple SDK — build scripts must
343365
# use native GCC instead to compile host C code (e.g., SQLite).
@@ -447,8 +469,9 @@ RUSTFLAGS="--remap-path-prefix=${DISTSRC}=. --remap-path-prefix=/gnu/store=/usr"
447469

448470
# For cross-compilation targets, set up the Rust sysroot.
449471
case "$HOST" in
450-
*mingw*)
451-
# Windows: Guix's make-rust-sysroot built libstd; use the profile.
472+
*mingw*|aarch64-linux-gnu)
473+
# Windows / aarch64 Linux: Guix's make-rust-sysroot built libstd;
474+
# use the profile as the sysroot.
452475
RUSTFLAGS="${RUSTFLAGS} --sysroot=${GUIX_ENVIRONMENT}"
453476
;;
454477
*darwin*)
@@ -674,7 +697,7 @@ cp "$binary" "${INSTALLPATH}/${BINARY_NAME}"
674697

675698
case "$HOST" in
676699
*linux*)
677-
patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 --remove-rpath "${INSTALLPATH}/${BINARY_NAME}"
700+
patchelf --set-interpreter "${DYNAMIC_LINKER}" --remove-rpath "${INSTALLPATH}/${BINARY_NAME}"
678701

679702
interp="$(readelf -l "${INSTALLPATH}/${BINARY_NAME}" | sed -n 's@.*Requesting program interpreter: \(.*\)]@\1@p')"
680703
runpath="$(readelf -d "${INSTALLPATH}/${BINARY_NAME}" | sed -n 's@.*Library runpath: \[\(.*\)\]@\1@p')"

contrib/guix/manifest.scm

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ FILE-NAME found in ./patches relative to the current file."
197197
(define-public x86_64-linux-gnu-toolchain
198198
(make-ckb-cross-toolchain "x86_64-linux-gnu"))
199199

200+
(define-public aarch64-linux-gnu-toolchain
201+
(make-ckb-cross-toolchain "aarch64-linux-gnu"))
202+
200203
;;;
201204
;;; Windows (MinGW-w64) cross-toolchain.
202205
;;; Reference: https://github.com/bitcoin/bitcoin/blob/master/contrib/guix/manifest.scm
@@ -275,6 +278,14 @@ FILE-NAME found in ./patches relative to the current file."
275278
#:xbinutils (cross-binutils "x86_64-linux-gnu"))
276279
#:xbinutils (cross-binutils "x86_64-linux-gnu")))
277280

281+
(define aarch64-linux-gnu-kernel-headers
282+
(cross-kernel-headers "aarch64-linux-gnu"
283+
#:linux-headers base-linux-kernel-headers
284+
#:xgcc (cross-gcc "aarch64-linux-gnu"
285+
#:xgcc linux-base-gcc
286+
#:xbinutils (cross-binutils "aarch64-linux-gnu"))
287+
#:xbinutils (cross-binutils "aarch64-linux-gnu")))
288+
278289
(define-public openssl-glibc-2.31
279290
(package
280291
(inherit openssl)
@@ -319,6 +330,44 @@ FILE-NAME found in ./patches relative to the current file."
319330
;; This is expected; the final binary handles RUNPATH via patchelf.
320331
(delete 'validate-runpath))))))
321332

333+
(define-public openssl-aarch64-glibc-2.31
334+
(package
335+
(inherit openssl)
336+
(name "openssl-aarch64-glibc-2.31")
337+
(native-inputs
338+
`(("cross-toolchain" ,aarch64-linux-gnu-toolchain)
339+
("cross-kernel-headers" ,aarch64-linux-gnu-kernel-headers)
340+
("perl" ,perl)))
341+
(arguments
342+
(list
343+
#:tests? #f
344+
#:configure-flags #~'()
345+
#:phases
346+
#~(modify-phases %standard-phases
347+
(replace 'configure
348+
(lambda* (#:key outputs #:allow-other-keys)
349+
(let ((out (assoc-ref outputs "out")))
350+
(invoke "perl" "./Configure"
351+
"linux-aarch64"
352+
(string-append "--prefix=" out)
353+
"--cross-compile-prefix=aarch64-linux-gnu-"
354+
"shared"
355+
"no-tests"))))
356+
(replace 'build
357+
(lambda* (#:key inputs parallel-build? #:allow-other-keys)
358+
(let* ((kernel-headers
359+
(assoc-ref inputs "cross-kernel-headers"))
360+
(jobs (if parallel-build?
361+
(number->string (parallel-job-count))
362+
"1")))
363+
(apply invoke "make" "-j" jobs
364+
(if kernel-headers
365+
(list (string-append
366+
"CPPFLAGS=-I" kernel-headers "/include"))
367+
'())))))
368+
(delete 'check)
369+
(delete 'validate-runpath))))))
370+
322371
;;;
323372
;;; Final manifest — select packages based on the HOST environment variable.
324373
;;;
@@ -357,9 +406,23 @@ FILE-NAME found in ./patches relative to the current file."
357406
(let ((target (or (getenv "HOST") "")))
358407
(cond
359408
((string-contains target "-linux-")
360-
(list x86_64-linux-gnu-toolchain
361-
openssl-glibc-2.31
362-
patchelf))
409+
(cond
410+
((string-prefix? "x86_64-" target)
411+
(list x86_64-linux-gnu-toolchain
412+
openssl-glibc-2.31
413+
patchelf))
414+
((string-prefix? "aarch64-" target)
415+
;; aarch64 cross: rustc ships std for the build host only
416+
;; (x86_64-unknown-linux-gnu), so we need a Rust sysroot containing
417+
;; library/std for aarch64. make-rust-sysroot/implementation builds
418+
;; it via x.py using the pinned rust-1.92 source.
419+
(let ((make-rust-sysroot/impl
420+
(@@ (gnu packages rust) make-rust-sysroot/implementation)))
421+
(list aarch64-linux-gnu-toolchain
422+
(make-rust-sysroot/impl "aarch64-linux-gnu" rust-1.92)
423+
openssl-aarch64-glibc-2.31
424+
patchelf)))
425+
(else '())))
363426
((string-suffix? "-mingw32" target)
364427
;; Rust sysroot (libstd) for Windows, built from source via x.py.
365428
;; Must use the same Rust version as the compiler (rust-1.92) —

contrib/guix/symbol-check.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@
1717
MAX_VERSIONS = {
1818
"GLIBC": {
1919
lief.ELF.ARCH.X86_64: (2, 31),
20+
lief.ELF.ARCH.AARCH64: (2, 31),
2021
},
2122
}
2223

2324
ELF_INTERPRETER_NAMES = {
2425
lief.ELF.ARCH.X86_64: {
2526
lief.Header.ENDIANNESS.LITTLE: "/lib64/ld-linux-x86-64.so.2",
2627
},
28+
lief.ELF.ARCH.AARCH64: {
29+
lief.Header.ENDIANNESS.LITTLE: "/lib/ld-linux-aarch64.so.1",
30+
},
2731
}
2832

2933
ELF_ALLOWED_LIBRARIES = {
@@ -35,6 +39,7 @@
3539
"libgcc_s.so.1",
3640
"libstdc++.so.6",
3741
"ld-linux-x86-64.so.2",
42+
"ld-linux-aarch64.so.1",
3843
"libssl.so.3",
3944
"libcrypto.so.3",
4045
}

0 commit comments

Comments
 (0)