guix: texlive-build-system: Improvements on non-trivial packages.

* guix/build/texlive-build-system.scm (build): Ignore temporary build files
when moving runfiles around.  Remove ".drv" source files prior to compiling
files.  Remove need for #:TEX-DIRECTORY keyword.  Handle ".ins" and ".dtx"
files in different directories.
(install): Install docfiles in "doc" output when available.
* guix/build-system/texlive.scm (texlive-build): Remove #:TEX-DIRECTORY.
* doc/guix.texi (Build Systems): Remove reference to #:TEX-DIRECTORY in
TEXLIVE-BUILD-SYSTEM documentation.  Also mention it now tries to compile
".dtx" files when there is no ".ins" file.
This commit is contained in:
Nicolas Goaziou 2023-05-06 07:26:01 +02:00
parent 4e11cac6be
commit 3f22dabc2a
No known key found for this signature in database
GPG key ID: DA00B4F048E92F2D
3 changed files with 107 additions and 25 deletions

View file

@ -10001,17 +10001,16 @@ used to build TeX packages in batch mode with a specified engine. The
build system sets the @env{TEXINPUTS} variable to find all TeX source
files in the inputs.
By default it runs @code{luatex} on all files ending on @code{ins}. A
different engine and format can be specified with the
@code{#:tex-format} argument. Different build targets can be specified
with the @code{#:build-targets} argument, which expects a list of file
names. The build system adds only @code{texlive-bin} and
By default it tries to run @code{luatex} on all @file{.ins} files, and
if it fails to find any, on all @file{.dtx} files. A different engine
and format can be specified with the @code{#:tex-format} argument.
Different build targets can be specified with the @code{#:build-targets}
argument, which expects a list of file names.
The build system adds only @code{texlive-bin} and
@code{texlive-latex-base} (both from @code{(gnu packages tex}) to the
inputs. Both can be overridden with the arguments @code{#:texlive-bin}
and @code{#:texlive-latex-base}, respectively.
The @code{#:tex-directory} parameter tells the build system where to
install the built files under the texmf tree.
@end defvar
@defvar ruby-build-system

View file

@ -130,7 +130,6 @@ (define* (texlive-build name inputs
#:key
source
(tests? #f)
tex-directory
(build-targets #f)
(tex-engine #f)
@ -161,7 +160,6 @@ (define builder
#$(with-build-variables inputs outputs
#~(texlive-build #:name #$name
#:source #+source
#:tex-directory #$tex-directory
#:build-targets #$build-targets
#:tex-engine #$(if tex-engine
tex-engine

View file

@ -2,6 +2,7 @@
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2021 Thiago Jung Bauermann <bauermann@kolabnow.com>
;;; Copyright © 2023 Nicolas Goaziou <mail@nicolasgoaziou.fr>
;;;
;;; This file is part of GNU Guix.
;;;
@ -22,8 +23,9 @@ (define-module (guix build texlive-build-system)
#:use-module ((guix build gnu-build-system) #:prefix gnu:)
#:use-module (guix build utils)
#:use-module (guix build union)
#:use-module (ice-9 match)
#:use-module (ice-9 format)
#:use-module (ice-9 ftw)
#:use-module (ice-9 match)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:export (%standard-phases
@ -35,33 +37,116 @@ (define-module (guix build texlive-build-system)
;;
;; Code:
(define (compile-with-latex engine format file)
(define (runfiles-root-directories)
"Return list of root directories containing runfiles."
(scandir "."
(negate
(cut member <> '("." ".." "build" "doc" "source")))))
(define* (delete-drv-files #:rest _)
"Delete pre-generated \".drv\" files in order to prevent build failures."
(when (file-exists? "source")
(for-each delete-file (find-files "source" "\\.drv$"))))
(define (compile-with-latex engine format output file)
(invoke engine
"-interaction=nonstopmode"
"-output-directory=build"
(string-append "-output-directory=" output)
(if format (string-append "&" format) "-ini")
file))
(define* (build #:key inputs build-targets tex-engine tex-format
#:allow-other-keys)
(mkdir "build")
(for-each (cut compile-with-latex tex-engine tex-format <>)
(if build-targets build-targets
(scandir "." (cut string-suffix? ".ins" <>)))))
(let ((targets
(cond
(build-targets
;; Collect the relative file names of all the specified targets.
(append-map (lambda (target)
(find-files "source"
(lambda (f _)
(string-suffix? (string-append "/" target)
f))))
build-targets))
((directory-exists? "source")
;; Prioritize ".ins" files over ".dtx" files. There's no
;; scientific reasoning here; it just seems to work better.
(match (find-files "source" "\\.ins$")
(() (find-files "source" "\\.dtx$"))
(files files)))
(else '()))))
(unless (null? targets)
(let ((output (string-append (getcwd) "/build")))
(mkdir-p output)
(for-each (lambda (target)
(with-directory-excursion (dirname target)
(compile-with-latex tex-engine
tex-format
output
(basename target))))
targets))
;; Now move generated files from the "build" directory into the rest of
;; the source tree, effectively replacing downloaded files.
(define* (install #:key outputs tex-directory #:allow-other-keys)
(let* ((out (assoc-ref outputs "out"))
(target (string-append
out "/share/texmf-dist/tex/" tex-directory)))
(mkdir-p target)
(for-each delete-file (find-files "." "\\.(log|aux)$"))
(for-each (cut install-file <> target)
(find-files "build" ".*"))))
;; Documentation may have been generated, but replace only runfiles,
;; i.e., files that belong neither to "doc" nor "source" trees.
;;
;; In TeX Live, all packages are fully pre-generated. As a consequence,
;; a generated file from the "build" top directory absent from the rest
;; of the tree is deemed unnecessary and can safely be ignored.
(let ((runfiles (append-map (cut find-files <>)
(runfiles-root-directories))))
(for-each (lambda (file)
(match (filter
(cut string-suffix?
(string-drop file (string-length "build"))
<>)
runfiles)
;; Current file is not a runfile. Ignore it.
(() #f)
;; One candidate only. Replace it with the one just
;; generated.
((destination)
(let ((target (dirname destination)))
(install-file file target)
(format #t "re-generated file ~s in ~s~%"
(basename file)
target)))
;; Multiple candidates! Not much can be done.
;; Hopefully, this should never happen.
(_
(format (current-error-port)
"warning: ambiguous localization of file ~s; \
ignoring it~%"
(basename file)))))
;; Preserve the relative file name of the generated file in
;; order to be more accurate when looking for the
;; corresponding runfile in the tree.
(find-files "build"))))))
(define* (install #:key outputs #:allow-other-keys)
(let ((out (assoc-ref outputs "out"))
(doc (assoc-ref outputs "doc")))
;; Take care of documentation.
(when (directory-exists? "doc")
(unless doc
(format (current-error-port)
"warning: missing 'doc' output for package documentation~%"))
(let ((doc-dir (string-append (or doc out) "/share/texmf-dist/doc")))
(mkdir-p doc-dir)
(copy-recursively "doc" doc-dir)))
;; Handle runfiles.
(let ((texmf (string-append (assoc-ref outputs "out") "/share/texmf-dist")))
(for-each (lambda (root)
(let ((destination (string-append texmf "/" root)))
(mkdir-p destination)
(copy-recursively root destination)))
(runfiles-root-directories)))))
(define %standard-phases
(modify-phases gnu:%standard-phases
(delete 'bootstrap)
(delete 'configure)
(add-before 'build 'delete-drv-files delete-drv-files)
(replace 'build build)
(delete 'check)
(replace 'install install)))