diff --git a/Makefile.am b/Makefile.am index 908c48b4ef..403808b0f6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -284,6 +284,7 @@ MODULES = \ guix/build/bournish.scm \ guix/build/qt-utils.scm \ guix/build/zig-build-system.scm \ + guix/build/zig-utils.scm \ guix/build/make-bootstrap.scm \ guix/build/toml.scm \ guix/search-paths.scm \ diff --git a/gnu/packages/zig.scm b/gnu/packages/zig.scm index 62e224b760..99335c5404 100644 --- a/gnu/packages/zig.scm +++ b/gnu/packages/zig.scm @@ -23,6 +23,7 @@ (define-module (gnu packages zig) #:use-module (guix gexp) #:use-module (guix packages) + #:use-module (guix platform) #:use-module (guix utils) #:use-module (guix download) #:use-module (guix git-download) @@ -87,11 +88,24 @@ (define-public zig-0.9 (build-system cmake-build-system) (arguments (list + #:imported-modules + (cons '(guix build zig-utils) + %cmake-build-system-modules) + #:modules + (cons '(guix build zig-utils) + '((guix build cmake-build-system) + (guix build utils))) #:configure-flags - #~(list #$@(if (%current-target-system) - (list (string-append "-DZIG_TARGET_TRIPLE=" - (%current-target-system))) - '())) + #~(list (string-append "-DZIG_LIB_DIR=" #$output "/lib/zig") + "-DZIG_TARGET_MCPU=baseline" + (string-append + "-DZIG_TARGET_TRIPLE=" + (zig-target + #$(platform-target + (lookup-platform-by-target-or-system + (or (%current-target-system) + (%current-system)))))) + "-DZIG_USE_LLVM_CONFIG=ON") #:out-of-source? #f ; for tests ;; There are too many unclear test failures. #:tests? (not (or (target-riscv64?) @@ -114,15 +128,14 @@ (define-public zig-0.9 ;; Is this symbol x86 only in glibc? ((".*link_static_lib_as_system_lib.*") ""))))) '()) - (add-after 'configure 'set-cache-dir - (lambda _ - ;; Set cache dir, otherwise Zig looks for `$HOME/.cache'. - (setenv "ZIG_GLOBAL_CACHE_DIR" - (string-append (getcwd) "/zig-cache")))) + (add-before 'configure 'zig-configure zig-configure) (delete 'check) (add-after 'install 'check (lambda* (#:key tests? #:allow-other-keys) (when tests? + ;; error(libc_installation): msvc_lib_dir may not be empty for + ;; windows-msvc. + (unsetenv "ZIG_LIBC") (invoke (string-append #$output "/bin/zig") ;; Testing the standard library takes >7.5GB RAM, and ;; will fail if it is OOM-killed. The 'test-toolchain' @@ -222,20 +235,13 @@ (define-public zig-0.10 ((#:tests? _ #t) (not (%current-target-system))) ((#:configure-flags flags ''()) - #~(cons* "-DZIG_TARGET_MCPU=baseline" - "-DZIG_SHARED_LLVM=ON" - (string-append "-DZIG_LIB_DIR=" #$output "/lib/zig") - #$flags)) + #~(cons "-DZIG_SHARED_LLVM=ON" + #$flags)) ((#:phases phases '%standard-phases) #~(modify-phases #$phases #$@(if (target-riscv64?) `((delete 'adjust-tests)) '()) - (add-after 'unpack 'set-CC - (lambda _ - ;; Set CC, since the stage 2 zig relies on it to find the libc - ;; installation, and otherwise silently links against its own. - (setenv "CC" #$(cc-for-target)))) (add-after 'patch-source-shebangs 'patch-more-shebangs (lambda* (#:key inputs #:allow-other-keys) ;; Zig uses information about an ELF file to determine the @@ -245,6 +251,9 @@ (define-public zig-0.10 (replace 'check (lambda* (#:key tests? #:allow-other-keys) (when tests? + ;; error(libc_installation): msvc_lib_dir may not be empty for + ;; windows-msvc. + (unsetenv "ZIG_LIBC") (invoke (string-append #$output "/bin/zig") "build" "test" ;; We're not testing the compiler bootstrap chain. @@ -314,6 +323,13 @@ (define zig-0.10.0-610 (substitute-keyword-arguments (package-arguments base) ;; Patch for fixing RUNPATH not applied to intermediate versions. ((#:validate-runpath? _ #t) #f) + ;; Patch for cross-compilation not applied to intermediate versions. + ((#:modules modules '()) + (cons '(srfi srfi-1) modules)) + ((#:configure-flags flags ''()) + #~(filter (lambda (flag) + (not (string-contains flag "ZIG_TARGET_TRIPLE"))) + #$flags)) ;; Disable tests for intermediate versions. ((#:tests? _ #t) #f) ((#:phases phases '%standard-phases) diff --git a/guix/build-system/zig.scm b/guix/build-system/zig.scm index ad8a96b607..82df75729c 100644 --- a/guix/build-system/zig.scm +++ b/guix/build-system/zig.scm @@ -23,6 +23,7 @@ (define-module (guix build-system zig) #:use-module (guix gexp) #:use-module (guix monads) #:use-module (guix packages) + #:use-module (guix platform) #:use-module (guix build-system) #:use-module (guix build-system gnu) #:use-module (ice-9 match) @@ -39,6 +40,7 @@ (define (default-zig) (define %zig-build-system-modules ;; Build-side modules imported by default. `((guix build zig-build-system) + (guix build zig-utils) ,@%default-gnu-imported-modules)) (define* (zig-build name inputs @@ -67,6 +69,9 @@ (define builder #:system #$system #:test-target #$test-target #:zig-build-flags #$zig-build-flags + ;; For reproducibility. + #:zig-build-target #$(platform-target + (lookup-platform-by-system system)) #:zig-test-flags #$zig-test-flags #:zig-release-type #$zig-release-type #:tests? #$tests? @@ -137,6 +142,7 @@ (define %outputs search-path-specification->sexp native-search-paths) #:zig-build-flags #$zig-build-flags + #:zig-build-target #$target #:zig-test-flags #$zig-test-flags #:zig-release-type #$zig-release-type #:zig-destdir #$zig-destdir diff --git a/guix/build/zig-build-system.scm b/guix/build/zig-build-system.scm index 9959a95ce4..75ebdb7ca9 100644 --- a/guix/build/zig-build-system.scm +++ b/guix/build/zig-build-system.scm @@ -20,6 +20,7 @@ (define-module (guix build zig-build-system) #:use-module ((guix build gnu-build-system) #:prefix gnu:) #:use-module (guix build utils) + #:use-module (guix build zig-utils) #:use-module (ice-9 popen) #:use-module (ice-9 rdelim) #:use-module (ice-9 ftw) @@ -33,55 +34,12 @@ (define-module (guix build zig-build-system) ;; Interesting guide here: ;; https://github.com/riverwm/river/blob/master/PACKAGING.md -(define global-cache-dir "zig-cache") - -(define* (configure #:key inputs target #:allow-other-keys) - ;; Set cache dir, otherwise Zig looks for `$HOME/.cache'. - (setenv "ZIG_GLOBAL_CACHE_DIR" global-cache-dir) - - (setenv "PKG_CONFIG" - (if target - (string-append target "-pkg-config") - "pkg-config")) - - ;; Libc paths for target. - (let ((libc (assoc-ref inputs (if target "cross-libc" "libc"))) - (port (open-file "/tmp/guix-zig-libc-paths" "w" #:encoding "utf8"))) - (display - (string-append "\ -include_dir=" libc "/include -sys_include_dir=" libc "/include -crt_dir=" libc "/lib -msvc_lib_dir= -kernel32_lib_dir= -gcc_dir=") - port) - (close-port port)) - (setenv "ZIG_LIBC" "/tmp/guix-zig-libc-paths")) - -(define (zig-target target) - (cond - ((string=? target "i586-pc-gnu") - "x86-hurd-gnu") - ((string=? target "i686-linux-gnu") - "x86-linux-gnu") - ((string=? target "i686-w64-mingw32") - "x86-windows-gnu") - ((string=? target "mips64el-linux-gnu") - "mips64el-linux-gnuabi64") - ((string=? target "powerpc-linux-gnu") - "powerpc-linux-gnueabi") - ((string=? target "x86_64-pc-gnu") - "x86_64-hurd-gnu") - ((string=? target "x86_64-w64-mingw32") - "x86_64-windows-gnu") - (else target))) (define* (build #:key zig-build-flags + zig-build-target zig-release-type ;; "safe", "fast" or "small" empty for a ;; debug build" - target #:allow-other-keys) "Build a given Zig package." @@ -91,9 +49,7 @@ (define* (build #:key "--prefix-lib-dir" "lib" "--prefix-exe-dir" "bin" "--prefix-include-dir" "include" - ,@(if target - (list (string-append "-Dtarget=" (zig-target target))) - '()) + ,(string-append "-Dtarget=" (zig-target zig-build-target)) ,@(if zig-release-type (list (string-append "-Drelease-" zig-release-type)) '()) @@ -125,7 +81,7 @@ (define* (install #:key inputs outputs #:allow-other-keys) (define %standard-phases (modify-phases gnu:%standard-phases (delete 'bootstrap) - (replace 'configure configure) + (replace 'configure zig-configure) (replace 'build build) (replace 'check check) (replace 'install install))) diff --git a/guix/build/zig-utils.scm b/guix/build/zig-utils.scm new file mode 100644 index 0000000000..67480df458 --- /dev/null +++ b/guix/build/zig-utils.scm @@ -0,0 +1,79 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2024 Hilton Chain +;;; Copyright © 2024 Efraim Flashner +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (guix build zig-utils) + #:use-module (guix build utils) + #:export (zig-configure + zig-target)) + +;;; +;;; Common procedures for zig and zig-build-system. +;;; + +(define* (zig-configure #:key inputs target #:allow-other-keys) + ;; Set cache dir, otherwise Zig looks for `$HOME/.cache'. + (setenv "ZIG_GLOBAL_CACHE_DIR" "/tmp/zig-cache") + (setenv "ZIG_LOCAL_CACHE_DIR" "/tmp/zig-cache") + + ;; XXX: Required for unpatched intermediade versions? + ;; Set CC, since the stage 2 zig relies on it to find the libc + ;; installation, and otherwise silently links against its own. + (setenv "CC" + (if target + (string-append target "-gcc") + "gcc")) + + (setenv "PKG_CONFIG" + (if target + (string-append target "-pkg-config") + "pkg-config")) + + ;; Libc paths for target. + (let ((libc (assoc-ref inputs (if target "cross-libc" "libc"))) + (port (open-file "/tmp/guix-zig-libc-paths" "w" #:encoding "utf8"))) + (when libc + (display + (string-append "\ +include_dir=" libc "/include +sys_include_dir=" libc "/include +crt_dir=" libc "/lib +msvc_lib_dir= +kernel32_lib_dir= +gcc_dir=") + port) + (setenv "ZIG_LIBC" "/tmp/guix-zig-libc-paths")) + (close-port port))) + +(define (zig-target target) + (cond + ((string=? target "i586-pc-gnu") + "x86-hurd-gnu") + ((string=? target "i686-linux-gnu") + "x86-linux-gnu") + ((string=? target "i686-w64-mingw32") + "x86-windows-gnu") + ((string=? target "mips64el-linux-gnu") + "mips64el-linux-gnuabi64") + ((string=? target "powerpc-linux-gnu") + "powerpc-linux-gnueabi") + ((string=? target "x86_64-pc-gnu") + "x86_64-hurd-gnu") + ((string=? target "x86_64-w64-mingw32") + "x86_64-windows-gnu") + (else target)))