~ruther/guix-local

3ef8c9307ce10ca59af9bcf84161a88fd08310e7 — Hilton Chain 1 year, 5 months ago 05bbf0e
gnu: zig: Build reproducibly.

* guix/build/zig-utils.scm: New file.
* Makefile.am (MODULES): Add it.
* guix/build-system/zig.scm (%zig-build-system-modules): Add it.
(zig-build,zig-cross-build): Add #:zig-build-target.
* guix/build/zig-build-system.scm (zig-target): Move to (guix build zig-utils).
(configure): Move to (guix build zig-utils) as zig-configure.
(build): Replace target with zig-build-target.
(%standard-phases): Adjust accordingly.
* gnu/packages/zig.scm (zig-0.9)[arguments]<#:imported-modules,#:modules>: Add
zig-build-system modules.
<#:configure-flags>: Set ZIG_TARGET_TRIPLE for native builds too.
Move applicable flags from zig-0.10 here.
<#:phases>: Apply 'zig-configure.
Unset ZIG_LIBC in 'check.
Remove 'set-cache-dir.
(zig-0.10)[arguments]<#:configure-flags>: Adjust accordingly.
(zig-0.10.0-610)[arguments]<#:configure-flags>: Remove ZIG_TARGET_TRIPLE.
M Makefile.am => Makefile.am +1 -0
@@ 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				\

M gnu/packages/zig.scm => gnu/packages/zig.scm +34 -18
@@ 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 @@
    (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 @@
                         ;; 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 @@ toolchain.  Among other features it provides
       ((#: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 @@ toolchain.  Among other features it provides
            (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 @@ toolchain.  Among other features it provides
       (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)

M guix/build-system/zig.scm => guix/build-system/zig.scm +6 -0
@@ 23,6 23,7 @@
  #: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 %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 @@
                     #: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 @@
                                                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

M guix/build/zig-build-system.scm => guix/build/zig-build-system.scm +4 -48
@@ 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 @@

;; 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 @@ gcc_dir=")
                     "--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 @@ gcc_dir=")
(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)))

A guix/build/zig-utils.scm => guix/build/zig-utils.scm +79 -0
@@ 0,0 1,79 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2024 Hilton Chain <hako@ultrarare.space>
;;; Copyright © 2024 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; 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 <http://www.gnu.org/licenses/>.

(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)))