aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi15
-rw-r--r--guix/build-system/texlive.scm2
-rw-r--r--guix/build/texlive-build-system.scm115
3 files changed, 107 insertions, 25 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index ee03de04dc..a1b624ad6f 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -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
diff --git a/guix/build-system/texlive.scm b/guix/build-system/texlive.scm
index aefd573d11..55e9cfee81 100644
--- a/guix/build-system/texlive.scm
+++ b/guix/build-system/texlive.scm
@@ -130,7 +130,6 @@ level package ID."
#:key
source
(tests? #f)
- tex-directory
(build-targets #f)
(tex-engine #f)
@@ -161,7 +160,6 @@ level package ID."
#$(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
diff --git a/guix/build/texlive-build-system.scm b/guix/build/texlive-build-system.scm
index 353fb934a6..9bc0ce31c1 100644
--- a/guix/build/texlive-build-system.scm
+++ b/guix/build/texlive-build-system.scm
@@ -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 @@
#: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 @@
;;
;; 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.
+
+ ;; 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 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" ".*"))))
+(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)))