rust: various build script fixes

This commit is contained in:
puck 2025-02-12 13:12:04 +00:00
parent e42315e67a
commit 8c129e33db
12 changed files with 307 additions and 165 deletions

View file

@ -16,7 +16,7 @@
<resolved-package-build-data> make-resolved-package-build-data resolved-package-build-data?
resolved-package-build-data-dep-info resolved-package-build-data-metadata resolved-package-build-data-rlib
resolved-package-build-data-transitive-dependencies
<resolved-package> make-resolved-package resolved-package?
resolved-package-name resolved-package-version resolved-package-fs
resolved-package-cargo-target resolved-package-enabled-features resolved-package-dependencies
@ -38,12 +38,23 @@
(define linker (delay #~,(string-append #$(force gcc) "/bin/cc")))
(define pkgconfig (delay (cdr (assoc "out" (nixpkgs "pkg-config")))))
(define protobuf (delay (cdr (assoc "out" (nixpkgs "protobuf")))))
(define magic (delay (cdr (assoc "out" (nixpkgs "file")))))
(define openssl (delay (let ((data (nixpkgs "openssl"))) #~,(begin #$(cdr (assoc "out" data)) #$(cdr (assoc "dev" data))))))
(define tvix-protos (delay (vfs-to-store (vfs-from-directory "/home/nix/store/dkjgsrg8knn406qh86c3mbxpbz2rjwfy-tvix-all-protos"))))
(define (build-script-env-overrides-for-crate crate-name)
(cond
((string=? crate-name "openssl-sys")
#~(("PATH" . ,(string-append #$(force pkgconfig) "/bin:" #$(force gcc) "/bin")) ("PKG_CONFIG_PATH" . ,(string-append #$(force openssl) "/lib/pkgconfig"))))
((or (string=? crate-name "ring") (string=? crate-name "bzip2-sys") (string=? crate-name "zstd-sys") (string=? crate-name "lzma-sys") (string=? crate-name "libmimalloc-sys"))
#~(("PATH" . ,(string-append #$(force gcc) "/bin"))))
((or (string=? crate-name "tvix-castore") (string=? crate-name "tvix-store") (string=? crate-name "tvix-build"))
#~(("PATH" . ,(string-append #$(force protobuf) "/bin")) ("PROTO_ROOT" . #$(force tvix-protos))))
((or (string=? crate-name "prost-wkt-types") (string=? crate-name "nar-bridge"))
#~(("PATH" . ,(string-append #$(force protobuf) "/bin"))))
((or (string=? crate-name "magic-sys"))
#~(("NIX_LDFLAGS" . ,(string-append #$(force magic) "/lib"))))
(else '())))
@ -57,14 +68,15 @@
(selected-dependencies resolver-selected-dependencies set-resolver-selected-dependencies!))
(define-record-type <resolved-package-build-data>
(make-resolved-package-build-data dep-info metadata rlib transitive-dependencies build-script-metadata bin-flags)
(make-resolved-package-build-data dep-info metadata rlib transitive-dependencies build-script-metadata bin-flags build-script-out)
resolved-package-build-data?
(dep-info resolved-package-build-data-dep-info set-resolved-package-build-data-dep-info!)
(metadata resolved-package-build-data-metadata set-resolved-package-build-data-metadata!)
(rlib resolved-package-build-data-rlib set-resolved-package-build-data-rlib!)
(transitive-dependencies resolved-package-build-data-transitive-dependencies set-resolved-package-build-data-transitive-dependencies!)
(build-script-metadata resolved-package-build-data-build-script-metadata)
(bin-flags resolved-package-build-data-bin-flags))
(bin-flags resolved-package-build-data-bin-flags)
(build-script-out resolved-package-build-data-build-script-out))
(define-record-type <resolved-package>
(make-resolved-package name version fs cargo-target target-dependencies crate enabled-features dependencies build-data build-script)
@ -291,6 +303,8 @@
(when (list? crate-type)
(set! crate-type 'rlib))
(define buildscript-metadata '())
(define buildscript-out #f)
(define crate-links '())
(define dependency-metadata '())
(define bin-flags '())
@ -327,7 +341,7 @@
("CARGO_PKG_RUST_VERSION" . "")
("CARGO_PKG_README" . "")
("CARGO_CRATE_NAME" . ,crate-name)))
; CARGO_BIN_NAME, OUT_DIR, CARGO_BIN_EXE_*: skipping for now
; CARGO_BIN_NAME, CARGO_BIN_EXE_*: skipping for now
; CARGO_PRIMARY_PACKAGE: not sensible here
; CARGO_TARGET_TMPDIR: integration/benchmark only
; CARGO_RUSTC_CURRENT_DIR: nightly only
@ -348,23 +362,28 @@
(else out)))
(when (resolved-package-build-script resolved)
;; "build" here is a misnomer; it's handling the .drv:s.
(unless (resolved-package-build-data (resolved-package-build-script resolved))
(build-package (resolved-package-build-script resolved)))
; For each package dependency, check if it has "links" metadata.
; Crate that immediately depend on other crates that have this metadata have
; the cargo::metadata pairs passed to the build script.
(mapping-for-each
(lambda (key value)
(unless (resolved-package-build-data value)
(build-package value))
(when (cargo-crate-links (resolved-package-crate value))
(for-each
(lambda (kv)
(set! dependency-metadata (cons (cons (string-map upcase-underscore (string-append "DEP_" (cargo-crate-links (resolved-package-crate value)) "_" (car kv))) (cdr kv)) dependency-metadata)))
(resolved-package-build-data-build-script-metadata (resolved-package-build-data value)))))
; Track (link-name . build-data) for each crate in immediate dependencies that applies
(set! crate-links (cons (cons (cargo-crate-links (resolved-package-crate value)) (resolved-package-build-data value)) crate-links))))
(resolved-package-dependencies resolved))
; Collect the necessary bits, and build the build script.
(let*-values
(((build-script) (cdr (resolved-package-build-data-rlib (resolved-package-build-data (resolved-package-build-script resolved)))))
((build-script-env) (build-script-env-overrides-for-crate (cargo-crate-name (resolved-package-crate resolved))))
((rewritten-features) (map (lambda (feature) (cons (string-map upcase-underscore (string-append "CARGO_FEATURE_" feature)) "")) (resolved-package-enabled-features resolved)))
((runner-output runner-outdir)
((runner-outdir runner-outpath)
(call-runner build-script crate-root
#~(
("RUSTC" . ,(string-append #$rustc "/bin/rustc"))
@ -373,40 +392,21 @@
("OPT_LEVEL" . "0")
("PROFILE" . "debug")
("DEBUG" . "true")
("_zilch_links" . ,(string-join #$(map (lambda (kv) #~,(string-append #$(resolved-package-build-data-build-script-out (cdr kv)) ":" (car kv))) crate-links) "!"))
,@(make-cfg-values-env cfg-values '())
,@dependency-metadata
,@rewritten-features
#$@build-script-env
; TODO: OUT_DIR, NUM_JOBS, OPT_LEVEL/DEBUG/PROFILE, DEP_*
; TODO: OUT_DIR, NUM_JOBS, OPT_LEVEL/DEBUG/PROFILE
; RUSTC/RUSTDOC?, RUSTC_LINKER? and CARGO_ENCODED_RUSTFLAGS
. #$rustc-env))))
(map
(lambda (v)
(if (pair? v)
(set! params `(#:cfg ,(string-append (car v) "=\"" (cdr v) "\"") . ,params))
(set! params `(#:cfg ,v . ,params))))
(build-script-output-cfg runner-output))
(set! buildscript-metadata (build-script-output-metadata runner-output))
(for-each (lambda (kv) (set! rustc-env (cons kv rustc-env))) (build-script-output-env runner-output))
; Pass the buildscript-out data to the next crate.
(set! buildscript-out runner-outpath)
; Pass cargo::rustc-cfg and cargo::rustc-check-cfg to the crate this build script belongs to.
; Also set OUT_DIR for include! and include_str! reasons.
(let ((old-rustc-env rustc-env))
(set! rustc-env #~(("OUT_DIR" . #$runner-outdir) . #$old-rustc-env)))
(for-each
(lambda (kv) (set! bin-flags `(#:link ,kv . ,bin-flags)))
(build-script-output-link-lib runner-output))
; TODO(puck): hack to workaround lack of store path passthrough
; This should be replaced with .... $something (a dir of all build script outputs?)
(unless (or (null? build-script-env) (null? bin-flags))
(let ((v (cadr bin-flags)))
(set-cdr! bin-flags (cons #~,(begin #$build-script-env #$runner-outdir v) (cddr bin-flags)))))
(for-each
(lambda (kv) (set! bin-flags `(#:search-path ,kv . ,bin-flags)))
(build-script-output-link-search runner-output))))
; TODO(puck): check-cfg wants check-cfg everywhere
;(map
; (lambda (v)
; (set! params `(#:check-cfg ,v . ,params)))
; (build-script-output-check-cfg runner-output))))
(set! rustc-env #~(("OUT_DIR" . #$runner-outdir) ("_zilch_proc" . #$runner-outpath) . #$old-rustc-env)))))
(define params-meta params)
(define transitive-dependencies '())
@ -443,8 +443,25 @@
(car rlib)
(zsymlink (cdr rlib)))) transitive-dependencies)))
(define all-crate-features '())
(for-each
(lambda (feat)
(set! all-crate-features
(cons
(string-append "\"" (car feat) "\"")
all-crate-features)))
(cargo-crate-features (resolved-package-crate resolved)))
(set! params `(check-cfg: ,(string-append "cfg(feature, values(" (string-join all-crate-features ",") "))") . ,params))
(define inherited-build-script-out '())
(define transitive-bin-flags '())
(for-each (lambda (dep) (set! transitive-bin-flags (append (resolved-package-build-data-bin-flags (resolved-package-build-data dep)) transitive-bin-flags))) transitive-dependencies)
(for-each
(lambda (dep)
(set! transitive-bin-flags (append (resolved-package-build-data-bin-flags (resolved-package-build-data dep)) transitive-bin-flags))
(when (resolved-package-build-data-build-script-out (resolved-package-build-data dep))
(set! inherited-build-script-out (cons (resolved-package-build-data-build-script-out (resolved-package-build-data dep)) inherited-build-script-out))))
transitive-dependencies)
(unless (eq? crate-type 'rlib)
(set! params `(codegen-flags: ("linker" . ,(force linker)) . ,params)))
@ -460,10 +477,12 @@
(when (eq? crate-type 'bin)
(set! rlib-name crate-name))
(when (or (eq? crate-type 'proc-macro) (eq? crate-type 'bin))
(set! params (append transitive-bin-flags params)))
; (when (or (eq? crate-type 'proc-macro) (eq? crate-type 'bin))
; (set! params (append transitive-bin-flags params)))
(when (eq? crate-type 'bin)
(set! params `(#:codegen-flags ("rpath" . "no") . ,params)))
(set! params `(#:codegen-flags ("rpath" . "no") . ,params))
(when (string=? crate-name "tvix_cli")
(set! params `(search-path: ("native" . ,#~,(string-append #$(force magic) "/lib")) . ,params))))
; Rust is nitpicky about the filenames, fix them with copious symlinking.
(define rlib-file (cdar (apply call-rustc `(,path ,rustc-env search-path: ("dependency" . ,transitive-dependencies-rlib) emits: (link: #t) ,@bin-flags . ,params))))
@ -477,7 +496,7 @@
(set! metadata (cons rmeta-name #~,(string-append #$(zdir rmeta-name (zsymlink metadata-file)) "/" rmeta-name)))
(store-path-materialize metadata-file))
(set-resolved-package-build-data! resolved (make-resolved-package-build-data dep-info metadata rlib transitive-dependencies buildscript-metadata bin-flags))
(set-resolved-package-build-data! resolved (make-resolved-package-build-data dep-info metadata rlib transitive-dependencies buildscript-metadata bin-flags buildscript-out))
rlib-file)
(define (matches-requirements ver req)