ant-build-system: Keep jar manifest.

* guix/build/ant-build-system.scm (default-build.xml): Generate default
manifest.
(strip-jar-timestamps): Repack jar archive with zip.
master
Ricardo Wurmus 2016-03-24 15:39:45 +01:00
parent ab50bba9f6
commit 9941e0812e
1 changed files with 17 additions and 12 deletions

View File

@ -65,13 +65,8 @@
(target (@ (name "jar") (target (@ (name "jar")
(depends "compile")) (depends "compile"))
(mkdir (@ (dir "${jar.dir}"))) (mkdir (@ (dir "${jar.dir}")))
;; We cannot use the simpler "jar" task here, because
;; there is no way to disable generation of a
;; manifest. We do not include a generated manifest
;; to ensure determinism, because we cannot easily
;; reset the ctime/mtime before creating the archive.
(exec (@ (executable "jar")) (exec (@ (executable "jar"))
(arg (@ (line ,(string-append "-Mcf ${jar.dir}/" jar-name (arg (@ (line ,(string-append "-cf ${jar.dir}/" jar-name
" -C ${classes.dir} .")))))) " -C ${classes.dir} ."))))))
(target (@ (name "install")) (target (@ (name "install"))
@ -105,16 +100,15 @@ INPUTS."
(zero? (apply system* `("ant" ,build-target ,@make-flags)))) (zero? (apply system* `("ant" ,build-target ,@make-flags))))
(define* (strip-jar-timestamps #:key outputs (define* (strip-jar-timestamps #:key outputs
#:allow-other-keys) #:allow-other-keys)
"Unpack all jar archives, reset the timestamp of all contained files, and "Unpack all jar archives, reset the timestamp of all contained files, and
repack them. This is necessary to ensure that archives are reproducible." repack them. This is necessary to ensure that archives are reproducible."
(define (repack-archive jar) (define (repack-archive jar)
(format #t "repacking ~a\n" jar) (format #t "repacking ~a\n" jar)
(let ((dir (mkdtemp! "jar-contents.XXXXXX"))) (let* ((dir (mkdtemp! "jar-contents.XXXXXX"))
(manifest (string-append dir "/META-INF/MANIFEST.MF")))
(and (with-directory-excursion dir (and (with-directory-excursion dir
(zero? (system* "jar" "xf" jar))) (zero? (system* "jar" "xf" jar)))
;; The manifest file contains timestamps
(for-each delete-file (find-files dir "MANIFEST.MF"))
(delete-file jar) (delete-file jar)
;; XXX: copied from (gnu build install) ;; XXX: copied from (gnu build install)
(for-each (lambda (file) (for-each (lambda (file)
@ -122,8 +116,19 @@ repack them. This is necessary to ensure that archives are reproducible."
(unless (eq? (stat:type s) 'symlink) (unless (eq? (stat:type s) 'symlink)
(utime file 0 0 0 0)))) (utime file 0 0 0 0))))
(find-files dir #:directories? #t)) (find-files dir #:directories? #t))
(unless (zero? (system* "jar" "-Mcf" jar "-C" dir "."))
(error "'jar' failed")) ;; The jar tool will always set the timestamp on the manifest file
;; and the containing directory to the current time, even when we
;; reuse an existing manifest file. To avoid this we use "zip"
;; instead of "jar". It is important that the manifest appears
;; first.
(with-directory-excursion dir
(let* ((files (find-files "." ".*" #:directories? #t))
(command (if (file-exists? manifest)
`("zip" "-X" ,jar ,manifest ,@files)
`("zip" "-X" ,jar ,@files))))
(unless (zero? (apply system* command))
(error "'zip' failed"))))
(utime jar 0 0) (utime jar 0 0)
#t))) #t)))