rust: support dependency-based env overrides for build scripts

This commit is contained in:
puck 2025-02-12 13:55:39 +00:00
parent 8c129e33db
commit 77c1de2e8e

View file

@ -43,13 +43,15 @@
(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)
(define (build-script-env-overrides-for-crate crate-name is-dependency)
(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"))
((and (string=? crate-name "pkg-config") is-dependency)
#~(("PATH" . ,(string-append #$(force pkgconfig) "/bin"))))
((and (string=? crate-name "openssl-sys") (not is-dependency))
#~(("PATH" . ,(string-append #$(force gcc) "/bin")) ("PKG_CONFIG_PATH" . ,(string-append #$(force openssl) "/lib/pkgconfig"))))
((and (member crate-name '("ring" "bzip2-sys" "zstd-sys" "lzma-sys" "libmimalloc-sys") string=?) (not is-dependency))
#~(("PATH" . ,(string-append #$(force gcc) "/bin"))))
((or (string=? crate-name "tvix-castore") (string=? crate-name "tvix-store") (string=? crate-name "tvix-build"))
((and (member crate-name '("tvix-castore" "tvix-store" "tvix-build") string=?) (not is-dependency))
#~(("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"))))
@ -285,7 +287,22 @@
; NOTE! string-map _has_ to return a char. non-chars are mistreated and cause memory corruption.
; TODO(puck): check this post-C6
(string-map (lambda (v) (if (char=? v #\-) #\_ v)) name))
(define (rewrite-env envs)
(define final-env (mapping (make-default-comparator)))
(for-each
(lambda (vars)
(for-each
(lambda (env-block)
(define value (mapping-ref/default final-env (car env-block) #f))
(if value
(set! value (string-append (cdr env-block) ":" value))
(set! value (cdr env-block)))
(set! final-env (mapping-set! final-env (car env-block) value)))
vars))
(reverse envs))
(mapping-map->list (lambda (k v) (cons k v)) final-env))
(define (build-package resolved)
; Info we need to collect:
; - enabled features
@ -361,18 +378,25 @@
(make-cfg-values-env (cdr l) (cons (cons env-name (or (cdar l) "")) out)))))
(else out)))
(define build-script-envs #f)
(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.
(set! build-script-envs (list (build-script-env-overrides-for-crate (cargo-crate-name (resolved-package-crate resolved)) #f)))
; For each package dependency, check if it has "links" metadata, as well as build script env overrides.
; 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))
(let ((env-override (build-script-env-overrides-for-crate (cargo-crate-name (resolved-package-crate value)) #t)))
(when env-override
(set! build-script-envs (cons env-override build-script-envs))))
(when (cargo-crate-links (resolved-package-crate 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))))
@ -381,7 +405,6 @@
; 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-outdir runner-outpath)
(call-runner build-script crate-root
@ -396,7 +419,7 @@
,@(make-cfg-values-env cfg-values '())
,@dependency-metadata
,@rewritten-features
#$@build-script-env
,@(rewrite-env #$build-script-envs)
; TODO: OUT_DIR, NUM_JOBS, OPT_LEVEL/DEBUG/PROFILE
; RUSTC/RUSTDOC?, RUSTC_LINKER? and CARGO_ENCODED_RUSTFLAGS
. #$rustc-env))))