build: cargo-build-system: Reset timestamps in crates.

This fixes reproducibility in rust crates from the package phase,
see <https://issues.guix.gnu.org/50015>.

* guix/build/cargo-build-system.scm (package): After running 'cargo
package' on the source unpack the tarball, reset the timestamps and
repack it.
This commit is contained in:
Efraim Flashner 2023-10-04 12:20:14 +03:00
parent 48e5110c25
commit fafbad0ce2
No known key found for this signature in database
GPG key ID: 41AAE7DCCA3D8351

View file

@ -242,7 +242,32 @@ (define* (package #:key
;;error: invalid inclusion of reserved file name Cargo.toml.orig in package source
(when (file-exists? "Cargo.toml.orig")
(delete-file "Cargo.toml.orig"))
(apply invoke `("cargo" "package" ,@cargo-package-flags))))
(apply invoke `("cargo" "package" ,@cargo-package-flags))
;; Then unpack the crate, reset the timestamp of all contained files, and
;; repack them. This is necessary to ensure that they are reproducible.
(with-directory-excursion "target/package"
(for-each
(lambda (crate)
(invoke "tar" "xf" crate)
(delete-file crate)
;; Some of the crate names have underscores, so we need to
;; search the current directory to find the unpacked crate.
(let ((dir
(car (scandir "."
(lambda (file)
(and (not (member file '("." "..")))
(not (string-suffix? ".crate" file))))))))
;; XXX: copied from (gnu build install)
(for-each (lambda (file)
(let ((s (lstat file)))
(unless (eq? (stat:type s) 'symlink)
(utime file 0 0 0 0))))
(find-files dir #:directories? #t))
(apply invoke "tar" "czf" (string-append dir ".crate")
(find-files dir #:directories? #t))
(delete-file-recursively dir)))
(find-files "." "\\.crate$")))))
(format #t "Not installing cargo sources, skipping `cargo package`.~%"))
#t)