guix: texlive-build-system: Generate font metrics.
* guix/build/texlive-build-system.scm (install-as-runfiles): (generate-font-metrics): New function. (build): Use INSTALL-AS-RUNFILES. (%standard-phases): Add new phase.
parent
10011abc44
commit
c09a05d06c
|
@ -10007,6 +10007,9 @@ 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.
|
||||
|
||||
It also generates font metrics (i.e., @file{.tfm} files) out of METAFONT
|
||||
files whenever possible.
|
||||
|
||||
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}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#:use-module (ice-9 ftw)
|
||||
#:use-module (ice-9 match)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (srfi srfi-2)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:export (%standard-phases
|
||||
texlive-build))
|
||||
|
@ -43,11 +44,111 @@
|
|||
(negate
|
||||
(cut member <> '("." ".." "build" "doc" "source")))))
|
||||
|
||||
(define (install-as-runfiles dir regexp)
|
||||
"Install files under DIR matching REGEXP on top of existing runfiles in the
|
||||
current tree. Sub-directories below DIR are preserved when looking for the
|
||||
runfile to replace. If a file has no matching runfile, it is 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 dir))
|
||||
<>)
|
||||
runfiles)
|
||||
;; Current file is not a runfile. Ignore it.
|
||||
(() #f)
|
||||
;; One candidate only. Replace it with the one from DIR.
|
||||
((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 location for file ~s; ignoring it~%"
|
||||
(basename file)))))
|
||||
(find-files dir regexp))))
|
||||
|
||||
(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* (generate-font-metrics #:key native-inputs inputs #:allow-other-keys)
|
||||
;; Decide what Metafont files to build by comparing them to the expected
|
||||
;; font metrics base names. Keep only files for which the two base names
|
||||
;; do match.
|
||||
(define (font-metrics root)
|
||||
(and (file-exists? root)
|
||||
(map (cut basename <> ".tfm") (find-files root "\\.tfm$"))))
|
||||
(define (font-files directory metrics)
|
||||
(if (file-exists? directory)
|
||||
(delete-duplicates
|
||||
(filter (lambda (f)
|
||||
(or (not metrics)
|
||||
(member (basename f ".mf") metrics)))
|
||||
(find-files directory "\\.mf$")))
|
||||
'()))
|
||||
;; Metafont files could be scattered across multiple directories. Treat
|
||||
;; each sub-directory as a separate font source.
|
||||
(define (font-sources root metrics)
|
||||
(delete-duplicates (map dirname (font-files root metrics))))
|
||||
(define (texlive-input? input)
|
||||
(string-prefix? "texlive-" input))
|
||||
(and-let* ((local-metrics (font-metrics "fonts/tfm"))
|
||||
(local-sources (font-sources "fonts/source" local-metrics))
|
||||
((not (null? local-sources))) ;nothing to generate: bail out
|
||||
(root (getcwd))
|
||||
(metafont
|
||||
(cond ((assoc-ref (or native-inputs inputs) "texlive-metafont") =>
|
||||
(cut string-append <> "/share/texmf-dist"))
|
||||
(else
|
||||
(error "Missing 'texlive-metafont' native input"))))
|
||||
;; Collect all font source files from texlive (native-)inputs so
|
||||
;; "mf" can know where to look for them.
|
||||
(font-inputs
|
||||
(delete-duplicates
|
||||
(append-map (match-lambda
|
||||
(((? (negate texlive-input?)) . _) '())
|
||||
(("texlive-bin" . _) '())
|
||||
(("texlive-metafont" . _)
|
||||
(list (string-append metafont "/metafont/base")))
|
||||
((_ . input)
|
||||
(font-sources input #f)))
|
||||
(or native-inputs inputs)))))
|
||||
;; Tell mf where to find "mf.base".
|
||||
(setenv "MFBASES" (string-append metafont "/web2c/"))
|
||||
(mkdir-p "build")
|
||||
(for-each
|
||||
(lambda (source)
|
||||
;; Tell "mf" where are the font source files. In case current package
|
||||
;; provides multiple sources, treat them separately.
|
||||
(setenv "MFINPUTS"
|
||||
(string-join (cons (string-append root "/" source)
|
||||
font-inputs)
|
||||
":"))
|
||||
;; Build font metrics (tfm).
|
||||
(with-directory-excursion source
|
||||
(for-each (lambda (font)
|
||||
(format #t "building font ~a~%" font)
|
||||
(invoke "mf" "-progname=mf"
|
||||
(string-append "-output-directory="
|
||||
root "/build")
|
||||
(string-append "\\"
|
||||
"mode:=ljfour; "
|
||||
"mag:=1; "
|
||||
"batchmode; "
|
||||
"input "
|
||||
(basename font ".mf"))))
|
||||
(font-files "." local-metrics)))
|
||||
;; Refresh font metrics at the appropriate location.
|
||||
(install-as-runfiles "build" "\\.tfm$"))
|
||||
local-sources)))
|
||||
|
||||
(define (compile-with-latex engine format output file)
|
||||
(invoke engine
|
||||
"-interaction=nonstopmode"
|
||||
|
@ -86,42 +187,14 @@
|
|||
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"))))))
|
||||
;; a generated file from the "build" top directory absent from the rest of
|
||||
;; the tree is deemed unnecessary and can safely be ignored.
|
||||
(install-as-runfiles "build" "."))))
|
||||
|
||||
(define* (install #:key outputs #:allow-other-keys)
|
||||
(let ((out (assoc-ref outputs "out"))
|
||||
|
@ -147,6 +220,7 @@ ignoring it~%"
|
|||
(delete 'bootstrap)
|
||||
(delete 'configure)
|
||||
(add-before 'build 'delete-drv-files delete-drv-files)
|
||||
(add-after 'delete-drv-files 'generate-font-metrics generate-font-metrics)
|
||||
(replace 'build build)
|
||||
(delete 'check)
|
||||
(replace 'install install)))
|
||||
|
|
Reference in New Issue