hako pushed a commit to branch wip-zig-bootstrap
in repository guix.
commit a41f66503b1cdd5b455e55fd1a684455caa0ae97
Author: Hilton Chain <[email protected]>
AuthorDate: Wed Nov 20 07:41:06 2024 +0800
build-system: zig: Support Zig package manager.
* guix/build-system/zig.scm (zig-build,zig-cross-build)
[#:install-source?,#:skip-build?]: New arguments.
[#:tests?]: Honor #:skip-build?.
* guix/build/zig-build-system.scm (zig-source-install-path)
(zig-input-install-path,unpack-dependencies): New procedures.
(%standard-phases): Add 'unpack-dependencies.
(build,install): Honor #:skip-build?.
* doc/guix.texi (Build Systems)[zig-build-system]: Update documentation.
* gnu/packages/zig.scm (zig-0.9)[native-search-paths]: Add
GUIX_ZIG_PACKAGE_PATH.
Use search paths defined in (guix search-paths).
(add-build.zig.zon,rename-zig-dependencies): New procedures.
* gnu/packages/ncdu.scm (ncdu)[arguments]: Don't install source.
* gnu/packages/zig-xyz.scm (river,tigerbeetle,zig-zls)[arguments]: Likewise.
Change-Id: I76ba483b67fdd26b33fa707a8d3cccc9f6a37e76
---
doc/guix.texi | 35 ++++++++++-----
gnu/packages/ncdu.scm | 3 +-
gnu/packages/zig-xyz.scm | 7 ++-
gnu/packages/zig.scm | 60 +++++++++++++++++++++-----
guix/build-system/zig.scm | 20 ++++++---
guix/build/zig-build-system.scm | 95 +++++++++++++++++++++++++++++++----------
6 files changed, 168 insertions(+), 52 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index f7b7569887..e58ef1827c 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -10181,17 +10181,30 @@ build system (@command{zig build} command).
Selecting this build system adds @code{zig} to the package inputs, in
addition to the packages of @code{gnu-build-system}.
-There is no @code{configure} phase because Zig packages typically do not
-need to be configured. The @code{#:zig-build-flags} parameter is a list of
-flags that are passed to the @code{zig} command during the build. The
-@code{#:zig-test-flags} parameter is a list of flags that are passed to the
-@code{zig test} command during the @code{check} phase. The default compiler
-package can be overridden with the @code{#:zig} argument.
-
-The optional @code{zig-release-type} parameter declares the type of release.
-Possible values are: @code{safe}, @code{fast}, or @code{small}. The default
-value is @code{#f}, which causes the release flag to be omitted from the
-@code{zig} command. That results in a @code{debug} build.
+This build system by default installs package source to output. This
+behavior can be disabled by setting @code{#:install-source?} parameter
+to @code{#f}.
+
+For packages that don't install anything and don't come with a test
+suite (likely library packages to be used by other Zig packages), you
+can set @code{#:skip-build?} parameter to @code{#t}, which skips
+@code{build} and @code{check} phases.
+
+The @code{configure} phase sets up environment for @command{zig build}.
+You need to add custom phases after it if you want to invoke
+@command{zig}.
+
+The @code{#:zig-build-flags} parameter is a list of flags that are
+passed to @command{zig build} in @code{build} phase. The
+@code{#:zig-test-flags} parameter is a list of flags that are passed to
+@command{zig build test} in @code{check} phase. The default compiler
+package can be overridden with the @code{#:zig} parameter.
+
+The optional @code{#:zig-release-type} parameter declares the type of
+release. Possible values are: @code{safe}, @code{fast}, or
+@code{small}. The default value is @code{#f}, which causes the release
+flag to be omitted from the @code{zig} command and results in a
+@code{debug} build.
@end defvar
@defvar scons-build-system
diff --git a/gnu/packages/ncdu.scm b/gnu/packages/ncdu.scm
index ab88f41dad..c49fefc077 100644
--- a/gnu/packages/ncdu.scm
+++ b/gnu/packages/ncdu.scm
@@ -72,7 +72,8 @@ ncurses installed.")
"01g5mpvsm78lkd0yin82gyancrl23npy69qcp3d60vmm72yiwirz"))))
(build-system zig-build-system)
(arguments
- (list #:zig zig-0.12))
+ (list #:zig zig-0.12
+ #:install-source? #f))
(inputs (list ncurses `(,zstd "lib")))
(native-inputs (list pkg-config))
(properties `((tunable? . #t)))))
diff --git a/gnu/packages/zig-xyz.scm b/gnu/packages/zig-xyz.scm
index 0cd08b6ac6..9c86dde556 100644
--- a/gnu/packages/zig-xyz.scm
+++ b/gnu/packages/zig-xyz.scm
@@ -53,6 +53,7 @@
(build-system zig-build-system)
(arguments
(list
+ #:install-source? #f
#:phases
#~(modify-phases %standard-phases
(add-after 'install 'install-wayland-session
@@ -98,6 +99,7 @@ directly from a tty using KMS/DRM.")
(arguments
(list
#:zig zig-0.9
+ #:install-source? #f
#:zig-release-type "safe"))
(synopsis "Distributed financial accounting database")
(description "TigerBeetle is a financial accounting database designed for
@@ -122,8 +124,9 @@ mission-critical safety and performance for financial
services.")
(build-system zig-build-system)
(inputs (list zig-0.10 python))
(arguments
- ;; The tests fail with memory leaks.
- (list #:tests? #f))
+ (list #:install-source? #f
+ ;; The tests fail with memory leaks.
+ #:tests? #f))
(synopsis "Zig language server")
(description
"Zig Language Server is a language server implementing the @acronym{LSP,
diff --git a/gnu/packages/zig.scm b/gnu/packages/zig.scm
index 218e00552a..3008983bab 100644
--- a/gnu/packages/zig.scm
+++ b/gnu/packages/zig.scm
@@ -23,6 +23,7 @@
#:use-module (guix gexp)
#:use-module (guix packages)
#:use-module (guix platform)
+ #:use-module (guix search-paths)
#:use-module (guix utils)
#:use-module (guix download)
#:use-module (guix git-download)
@@ -32,7 +33,48 @@
#:use-module (gnu packages compression)
#:use-module (gnu packages llvm)
#:use-module (gnu packages llvm-meta)
- #:use-module (gnu packages web))
+ #:use-module (gnu packages web)
+ #:export (add-build.zig.zon
+ rename-zig-dependencies))
+
+(define* (add-build.zig.zon name version dependencies #:optional (paths '("")))
+ "Snippet to generate build.zig.zon of DEPENDENCIES for package NAME@VERSION."
+ `(let ((port (open-file "build.zig.zon" "w" #:encoding "utf8")))
+ (format port "\
+.{
+ .name = \"~a\",
+ .version = \"~a\",
+ .paths = .{
+~{\
+ \"~a\",
+~}\
+ },
+ .dependencies = .{
+~{\
+ .@\"~a\" = .{
+ .url = \"\",
+ },
+~}\
+ },
+}~%" ,name ,version (quote ,paths) (quote ,dependencies))
+ (close-port port)))
+
+(define (rename-zig-dependencies mapping)
+ "Snippet to rename Zig dependencies in build.zig and build.zig.zon."
+ `(begin
+ (use-modules (ice-9 match)
+ (guix build utils))
+ (for-each
+ (match-lambda
+ ((old-name . new-name)
+ (begin
+ (substitute* "build.zig"
+ (((string-append "([Dd]ependency.\")" old-name) _ prefix)
+ (string-append prefix new-name)))
+ (substitute* "build.zig.zon"
+ (((format #f "\\.(@\")?~a\"?" old-name))
+ (format #f ".@\"~a\"" new-name))))))
+ (quote ,mapping))))
(define (zig-source version commit hash)
(origin
@@ -168,16 +210,12 @@
(list llvm-13
zig-0.9-glibc-abi-tool))
(native-search-paths
- (list
- (search-path-specification
- (variable "C_INCLUDE_PATH")
- (files '("include")))
- (search-path-specification
- (variable "CPLUS_INCLUDE_PATH")
- (files '("include/c++" "include")))
- (search-path-specification
- (variable "LIBRARY_PATH")
- (files '("lib" "lib64")))))
+ (list $C_INCLUDE_PATH
+ $CPLUS_INCLUDE_PATH
+ $LIBRARY_PATH
+ (search-path-specification
+ (variable "GUIX_ZIG_PACKAGE_PATH")
+ (files '("src/zig")))))
(synopsis "General purpose programming language and toolchain")
(description "Zig is a general-purpose programming language and
toolchain. Among other features it provides
diff --git a/guix/build-system/zig.scm b/guix/build-system/zig.scm
index 82df75729c..0b96490387 100644
--- a/guix/build-system/zig.scm
+++ b/guix/build-system/zig.scm
@@ -48,6 +48,8 @@
source
(tests? #t)
(test-target #f)
+ (install-source? #t)
+ (skip-build? #f)
(zig-build-flags ''())
(zig-test-flags ''())
(zig-release-type #f)
@@ -68,13 +70,15 @@
#:source #+source
#:system #$system
#:test-target #$test-target
+ #:install-source? #$install-source?
+ #:skip-build? #$skip-build?
#: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?
+ #:tests? #$(and tests? (not skip-build?))
#:phases #$phases
#:outputs #$(outputs->gexp outputs)
#:search-paths '#$(sexp->gexp
@@ -98,6 +102,8 @@
(native-search-paths '())
(tests? #t)
(test-target #f)
+ (install-source? #t)
+ (skip-build? #f)
(zig-build-flags ''())
(zig-test-flags ''())
(zig-destdir "out")
@@ -141,13 +147,15 @@
#:native-search-paths '#$(map
search-path-specification->sexp
native-search-paths)
+ #:install-source? #$install-source?
+ #:skip-build? #$skip-build?
#: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
#:zig-test-destdir #$zig-test-destdir
- #:tests? #$tests?
+ #:tests? #$(and tests? (not skip-build?))
#:search-paths '#$(sexp->gexp
(map search-path-specification->sexp
search-paths))))))
@@ -164,13 +172,13 @@
(define* (lower name
#:key source inputs native-inputs outputs system target
- (zig (default-zig))
+ (zig (default-zig)) (zig-inputs '())
#:allow-other-keys
#:rest arguments)
"Return a bag for NAME."
(define private-keywords
- '(#:target #:zig #:inputs #:native-inputs #:outputs))
+ '(#:target #:zig #:zig-inputs #:inputs #:native-inputs #:outputs))
(bag
(name name)
@@ -181,6 +189,7 @@
'())
,@`(("zig" ,zig))
,@native-inputs
+ ,@(if target '() zig-inputs)
,@(if target '() inputs)
,@(if target
;; Use the standard cross inputs of
@@ -189,7 +198,8 @@
'())
;; Keep the standard inputs of 'gnu-build-system'.
,@(standard-packages)))
- (host-inputs (if target inputs '()))
+ (host-inputs `(,@(if target zig-inputs '())
+ ,@(if target inputs '())))
(target-inputs (if target
(standard-cross-packages target 'target)
'()))
diff --git a/guix/build/zig-build-system.scm b/guix/build/zig-build-system.scm
index d721baf57c..5ead11b28a 100644
--- a/guix/build/zig-build-system.scm
+++ b/guix/build/zig-build-system.scm
@@ -23,38 +23,82 @@
#:use-module (ice-9 popen)
#:use-module (ice-9 rdelim)
#:use-module (ice-9 ftw)
- #:use-module (ice-9 format)
#:use-module (ice-9 match)
- #:use-module (rnrs io ports)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:export (%standard-phases
- zig-build))
+ zig-build
+ zig-source-install-path))
;; Interesting guide here:
;; https://github.com/riverwm/river/blob/master/PACKAGING.md
+(define (zig-source-install-path output)
+ (string-append output "/src/zig/" (strip-store-file-name output)))
+
+(define (zig-input-install-path input)
+ (zig-source-install-path
+ (dirname (dirname (dirname (canonicalize-path input))))))
+
+;; Use ‘zig fetch --name=NAME’ to overwrite dependency NAME and update hash in
+;; build.zig.zon.
+(define (unpack-dependencies . args)
+ "Unpack Zig dependencies from GUIX_ZIG_PACKAGE_PATH. Note that this phase
+asserts dependency names start with \"zig-\"."
+ (define zig-inputs
+ (append-map
+ (lambda (directory)
+ (map (lambda (input-name)
+ (cons input-name
+ (string-append directory "/" input-name)))
+ (scandir directory (negate (cut member <> '("." ".."))))))
+ (or (and=> (getenv "GUIX_ZIG_PACKAGE_PATH")
+ (cut string-split <> #\:))
+ '())))
+ ;; zig-aaa-0.1.2-3.456789a -> zig-aaa
+ ;; zig-bbb-2.3.3 -> zig-bbb
+ (define (strip-version input)
+ (let* ((name+version (string-split input #\-))
+ (guix-revision?
+ (not (= (length (string-split (last name+version) #\.))
+ 3))))
+ (string-join
+ (drop-right name+version (if guix-revision? 2 1))
+ "-")))
+ (for-each
+ (match-lambda
+ ((input-name . input-path)
+ (let ((call `("zig" "fetch"
+ ;; TODO: When supported, use a valid URL instead.
+ ;; See also <https://github.com/ziglang/zig/pull/21931>.
+ ,(zig-input-install-path input-path)
+ ,(string-append "--save=" (strip-version input-name)))))
+ (format #t "running: ~s~%" call)
+ (apply invoke call))))
+ (reverse zig-inputs)))
+
(define* (build #:key
zig-build-flags
zig-build-target
- zig-release-type ;; "safe", "fast" or "small" empty for a
- ;; debug build"
+ ;; "safe", "fast" or "small", empty for a "debug" build.
+ zig-release-type
+ skip-build?
#:allow-other-keys)
"Build a given Zig package."
-
- (setenv "DESTDIR" "out")
- (let ((call `("zig" "build"
- "--prefix" "" ;; Don't add /usr
- "--prefix-lib-dir" "lib"
- "--prefix-exe-dir" "bin"
- "--prefix-include-dir" "include"
- ,(string-append "-Dtarget=" (zig-target zig-build-target))
- ,@(if zig-release-type
- (list (string-append "-Drelease-" zig-release-type))
- '())
- ,@zig-build-flags)))
- (format #t "running: ~s~%" call)
- (apply invoke call)))
+ (when (not skip-build?)
+ (setenv "DESTDIR" "out")
+ (let ((call `("zig" "build"
+ "--prefix" "" ;; Don't add /usr
+ "--prefix-lib-dir" "lib"
+ "--prefix-exe-dir" "bin"
+ "--prefix-include-dir" "include"
+ ,(string-append "-Dtarget=" (zig-target zig-build-target))
+ ,@(if zig-release-type
+ (list (string-append "-Drelease-" zig-release-type))
+ '())
+ ,@zig-build-flags)))
+ (format #t "running: ~s~%" call)
+ (apply invoke call))))
(define* (check #:key tests?
zig-test-flags
@@ -72,15 +116,22 @@
(setenv "DESTDIR" old-destdir)
(unsetenv "DESTDIR")))))
-(define* (install #:key inputs outputs #:allow-other-keys)
+(define* (install #:key outputs install-source? #:allow-other-keys)
"Install a given Zig package."
- (let ((out (assoc-ref outputs "out")))
- (copy-recursively "out" out)))
+ (let* ((out (assoc-ref outputs "out"))
+ (source-install-path (zig-source-install-path out)))
+ (when (file-exists? "out")
+ (copy-recursively "out" out)
+ (delete-file-recursively "out"))
+ (when install-source?
+ (mkdir-p source-install-path)
+ (copy-recursively "." source-install-path))))
(define %standard-phases
(modify-phases gnu:%standard-phases
(delete 'bootstrap)
(replace 'configure zig-configure)
+ (add-after 'configure 'unpack-dependencies unpack-dependencies)
(replace 'build build)
(replace 'check check)
(replace 'install install)))