forked from auxolotl/core
329 lines
12 KiB
Bash
329 lines
12 KiB
Bash
# shellcheck shell=bash
|
|
|
|
# Replicate the post install phase of the upstream TeX Live installer.
|
|
#
|
|
# This script is based on the install-tl script and the TeXLive::TLUtils perl
|
|
# module, down to using the same (prefixed) function names and log messages.
|
|
#
|
|
# When updating to the next TeX Live release, review install-tl for changes and
|
|
# update this script accordingly.
|
|
|
|
### install-tl
|
|
|
|
# adjust texmf.cnf and texmfcnf.lua
|
|
installtl_do_texmf_cnf () {
|
|
# unlike install-tl, we make a copy of the entire texmf.cnf
|
|
# and point the binaries at $TEXMFCNF/texmf.cnf via wrappers
|
|
|
|
mkdir -p "$TEXMFCNF"
|
|
if [[ -e $texmfdist/web2c/texmfcnf.lua ]]; then
|
|
tlutils_info "writing texmfcnf.lua to $TEXMFCNF/texmfcnf.lua"
|
|
sed -e "s,\(TEXMFOS[ ]*=[ ]*\)[^\,]*,\1\"$texmfroot\",g" \
|
|
-e "s,\(TEXMFDIST[ ]*=[ ]*\)[^\,]*,\1\"$texmfdist\",g" \
|
|
-e "s,\(TEXMFSYSVAR[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFSYSVAR\",g" \
|
|
-e "s,\(TEXMFSYSCONFIG[ ]*=[ ]*\)[^\,]*,\1\"$TEXMFSYSCONFIG\",g" \
|
|
-e "s,\(TEXMFLOCAL[ ]*=[ ]*\)[^\,]*,\1\"$out/share/texmf-local\",g" \
|
|
-e "s,\$SELFAUTOLOC,$out,g" \
|
|
-e "s,selfautodir:/,$out/share/,g" \
|
|
-e "s,selfautodir:,$out/share/,g" \
|
|
-e "s,selfautoparent:/,$out/share/,g" \
|
|
-e "s,selfautoparent:,$out/share/,g" \
|
|
"$texmfdist/web2c/texmfcnf.lua" > "$TEXMFCNF/texmfcnf.lua"
|
|
fi
|
|
|
|
tlutils_info "writing texmf.cnf to $TEXMFCNF/texmf.cnf"
|
|
sed -e "s,\(TEXMFROOT[ ]*=[ ]*\)[^\,]*,\1$texmfroot,g" \
|
|
-e "s,\(TEXMFDIST[ ]*=[ ]*\)[^\,]*,\1$texmfdist,g" \
|
|
-e "s,\(TEXMFSYSVAR[ ]*=[ ]*\)[^\,]*,\1$TEXMFSYSVAR,g" \
|
|
-e "s,\(TEXMFSYSCONFIG[ ]*=[ ]*\)[^\,]*,\1$TEXMFSYSCONFIG,g" \
|
|
-e "s,\$SELFAUTOLOC,$out,g" \
|
|
-e "s,\$SELFAUTODIR,$out/share,g" \
|
|
-e "s,\$SELFAUTOPARENT,$out/share,g" \
|
|
-e "s,\$SELFAUTOGRANDPARENT,$out/share,g" \
|
|
"$texmfdist/web2c/texmf.cnf" > "$TEXMFCNF/texmf.cnf"
|
|
}
|
|
|
|
# run postaction scripts from texlive.tlpdb
|
|
# note that the other postactions (fileassoc, ...) are Windows only
|
|
installtl_do_tlpdb_postactions () {
|
|
local postaction postInterp
|
|
if [[ -n $postactionScripts ]] ; then
|
|
tlutils_info "running package-specific postactions"
|
|
for postaction in $postactionScripts ; do
|
|
# see TeXLive::TLUtils::_installtl_do_postaction_script
|
|
case "$postaction" in
|
|
*.pl)
|
|
postInterp=perl ;;
|
|
*.texlua)
|
|
postInterp=texlua ;;
|
|
*)
|
|
postInterp= ;;
|
|
esac
|
|
tlutils_info "${postInterp:+$postInterp }$postaction install $texmfroot"
|
|
FORCE_SOURCE_DATE=1 $postInterp "$texmfroot/$postaction" install "$texmfroot" >>"$TEXMFSYSVAR/postaction-${postaction##*/}.log"
|
|
done
|
|
tlutils_info "finished with package-specific postactions"
|
|
fi
|
|
}
|
|
|
|
installtl_do_path_adjustments () {
|
|
# here install-tl would add a system symlink to the man pages
|
|
# instead we run other nixpkgs related adjustments
|
|
|
|
# generate wrappers
|
|
tlutils_info "wrapping binaries"
|
|
|
|
local bash cmd extraPaths link path target wrapCount
|
|
bash="$(command -v bash)"
|
|
enable -f "${bash%/bin/bash}"/lib/bash/realpath realpath
|
|
|
|
# common runtime dependencies
|
|
for cmd in cat awk sed grep gs ; do
|
|
# do not fail if gs is absent
|
|
path="$(PATH="$HOST_PATH" command -v "$cmd" || :)"
|
|
if [[ -n $path ]] ; then
|
|
extraPaths="${extraPaths:+$extraPaths:}${path%/"$cmd"}"
|
|
fi
|
|
done
|
|
|
|
declare -i wrapCount=0
|
|
for link in "$out"/bin/* ; do
|
|
target="$(realpath "$link")"
|
|
|
|
# skip non-executable files (such as context.lua)
|
|
if [[ ! -x $target ]] ; then
|
|
continue
|
|
fi
|
|
|
|
if [[ ${target##*/} != "${link##*/}" ]] ; then
|
|
# detected alias with different basename, use immediate target of $link to preserve $0
|
|
# relevant for mktexfmt, repstopdf, ...
|
|
target="$(readlink "$link")"
|
|
fi
|
|
|
|
rm "$link"
|
|
makeWrapper "$target" "$link" \
|
|
--inherit-argv0 \
|
|
--prefix PATH : "$extraPaths:$out/bin" \
|
|
--set-default TEXMFCNF "$TEXMFCNF" \
|
|
--set-default FONTCONFIG_FILE "$fontconfigFile"
|
|
wrapCount=$((wrapCount + 1))
|
|
done
|
|
|
|
tlutils_info "wrapped $wrapCount binaries and scripts"
|
|
|
|
# generate format symlinks (using fmtutil.cnf)
|
|
tlutils_info "generating format symlinks"
|
|
texlinks --quiet "$out/bin"
|
|
|
|
# remove *-sys scripts since /nix/store is readonly
|
|
rm "$out"/bin/*-sys
|
|
|
|
# link TEXMFDIST in $out/share for backward compatibility
|
|
ln -s "$texmfdist" "$out"/share/texmf
|
|
|
|
# generate other outputs
|
|
local otherOutput otherOutputName
|
|
local otherOutputs="$otherOutputs"
|
|
for otherOutputName in $outputs ; do
|
|
if [[ $otherOutputName == out ]] ; then
|
|
continue
|
|
fi
|
|
otherOutput="${otherOutputs%% *}"
|
|
otherOutputs="${otherOutputs#* }"
|
|
ln -s "$otherOutput" "${!otherOutputName}"
|
|
done
|
|
}
|
|
|
|
# run all post install parts
|
|
installtl_do_postinst_stuff () {
|
|
installtl_do_texmf_cnf
|
|
|
|
# create various config files
|
|
# in principle, we could use writeText and share them across different
|
|
# environments, but the eval & build overhead is not worth the savings
|
|
tlutils_create_fmtutil
|
|
tlutils_create_updmap
|
|
tlutils_create_language_dat
|
|
tlutils_create_language_def
|
|
tlutils_create_language_lua
|
|
|
|
# make new files available
|
|
tlutils_info "running mktexlsr $TEXMFSYSVAR $TEXMFSYSCONFIG"
|
|
mktexlsr "$TEXMFSYSVAR" "$TEXMFSYSCONFIG"
|
|
|
|
# update font maps
|
|
tlutils_info "generating font maps"
|
|
updmap-sys --quiet --force --nohash 2>&1
|
|
# configure the paper size
|
|
# tlmgr --no-execute-actions paper letter
|
|
# install-tl: "rerun mktexlsr for updmap-sys and tlmgr paper updates"
|
|
tlutils_info "re-running mktexlsr $TEXMFSYSVAR $TEXMFSYSCONFIG"
|
|
mktexlsr "$TEXMFSYSVAR" "$TEXMFSYSCONFIG"
|
|
|
|
tlutils_update_context_cache
|
|
|
|
# generate formats
|
|
# install-tl would run fmtutil-sys $common_fmtutil_args --no-strict --all
|
|
# instead, we want fmtutil to exit with error on failure
|
|
if [[ -n $fmtutilCnf ]] ; then
|
|
tlutils_info "pre-generating all format files, be patient..."
|
|
# many formats still ignore SOURCE_DATE_EPOCH even when FORCE_SOURCE_DATE=1
|
|
# libfaketime fixes non-determinism related to timestamps ignoring FORCE_SOURCE_DATE
|
|
# we cannot fix further randomness caused by luatex; for further details, see
|
|
# https://salsa.debian.org/live-team/live-build/-/blob/master/examples/hooks/reproducible/2006-reproducible-texlive-binaries-fmt-files.hook.chroot#L52
|
|
# note that calling faketime and fmtutil is fragile (faketime uses LD_PRELOAD, fmtutil calls /bin/sh, causing potential glibc issues on non-NixOS)
|
|
# so we patch fmtutil to use faketime, rather than calling faketime fmtutil
|
|
substitute "$texmfdist"/scripts/texlive/fmtutil.pl fmtutil \
|
|
--replace-fail "my \$cmdline = \"\$eng -ini " "my \$cmdline = \"faketime -f '\@$(date +'%F %T' --date=@"$SOURCE_DATE_EPOCH") x0.001' \$eng -ini "
|
|
FORCE_SOURCE_DATE=1 perl fmtutil --quiet --strict --sys --all 2>&1 | grep '^fmtutil' # too verbose
|
|
fi
|
|
|
|
installtl_do_path_adjustments
|
|
|
|
installtl_do_tlpdb_postactions
|
|
|
|
# remove log files to improve reproducibility
|
|
find "$TEXMFSYSVAR" -name '*.log' -delete
|
|
}
|
|
|
|
### TeXLive::TLUtils
|
|
|
|
tlutils_info () {
|
|
printf '%s\n' "texlive: $*"
|
|
}
|
|
|
|
tlutils_create_fmtutil () {
|
|
# fmtutil.cnf created by install-tl already exists readonly in $texmfdist
|
|
# so here we need to *disable* the entries that are not in $fmtutilCnf
|
|
# and write the output in the writeable $TEXMFSYSVAR
|
|
|
|
local engine fmt line outFile sedExpr
|
|
outFile="$TEXMFSYSVAR"/web2c/fmtutil.cnf
|
|
|
|
tlutils_info "writing fmtutil.cnf to $outFile"
|
|
|
|
while IFS= read -r line ; do
|
|
# a line is 'fmt engine ...' or '#! fmt engine ...'
|
|
# (see fmtutil.pl::read_fmtutil_file)
|
|
line="${line#\#! }"
|
|
read -r fmt engine _ <<<"$line"
|
|
# if a line for the ($fmt,$engine) pair exists, remove it to avoid
|
|
# pointless warnings from fmtutil
|
|
sedExpr="$sedExpr /^(#! )?$fmt $engine /d;"
|
|
done <<<"$fmtutilCnf"
|
|
|
|
# disable all the remaining formats
|
|
sedExpr="$sedExpr /^[^#]/{ s/^/#! /p };"
|
|
|
|
{
|
|
echo "# Generated by nixpkgs"
|
|
sed -E -n -e "$sedExpr" "$texmfdist"/web2c/fmtutil.cnf
|
|
[[ -z $fmtutilCnf ]] || printf '%s' "$fmtutilCnf"
|
|
} >"$outFile"
|
|
}
|
|
|
|
tlutils_create_updmap () {
|
|
# updmap.cfg created by install-tl already exists readonly in $texmfdist
|
|
# so here we need to *disable* the entries that are not in $updmapCfg
|
|
# and write the output in the writeable $TEXMFSYSVAR
|
|
|
|
local line map outFile sedExpr
|
|
outFile="$TEXMFSYSVAR"/web2c/updmap.cfg
|
|
|
|
tlutils_info "writing updmap.cfg to $outFile"
|
|
|
|
while IFS= read -r line ; do
|
|
# a line is 'type map' or '#! type map'
|
|
# (see fmtutil.pl::read_updmap_file)
|
|
read -r _ map <<<"$line"
|
|
# if a line for $map exists, remove it to avoid
|
|
# pointless warnings from updmap
|
|
sedExpr="$sedExpr /^(#! )?[^ ]*Map $map$/d;"
|
|
done <<<"$updmapCfg"
|
|
|
|
# disable all the remaining font maps
|
|
sedExpr="$sedExpr /^[^ ]*Map/{ s/^/#! /p };"
|
|
|
|
{
|
|
echo "# Generated by nixpkgs"
|
|
sed -E -n -e "$sedExpr" "$texmfdist"/web2c/updmap.cfg
|
|
[[ -z $updmapCfg ]] || printf '%s' "$updmapCfg"
|
|
} >"$outFile"
|
|
}
|
|
|
|
tlutils__create_config_files () {
|
|
# simplified arguments
|
|
local header="$1"
|
|
local dest="$2"
|
|
local prefix="$3"
|
|
local lines="$4"
|
|
local suffix="$5"
|
|
if [[ -z "$header" || -e "$header" ]] ; then
|
|
tlutils_info "writing ${dest##*/} to $dest"
|
|
{
|
|
[[ -z $prefix ]] || printf '%s\n' "$prefix"
|
|
[[ ! -e $header ]] || cat "$header"
|
|
[[ -z $lines ]] || printf '%s\n' "$lines"
|
|
[[ -z $suffix ]] || printf '%s\n' "$suffix"
|
|
} >"$dest"
|
|
fi
|
|
}
|
|
|
|
tlutils_create_language_dat () {
|
|
tlutils__create_config_files \
|
|
"$texmfdist"/tex/generic/config/language.us \
|
|
"$TEXMFSYSVAR"/tex/generic/config/language.dat \
|
|
'% Generated by nixpkgs' \
|
|
"$languageDat" \
|
|
''
|
|
}
|
|
|
|
tlutils_create_language_def () {
|
|
tlutils__create_config_files \
|
|
"$texmfdist"/tex/generic/config/language.us.def \
|
|
"$TEXMFSYSVAR"/tex/generic/config/language.def \
|
|
'' \
|
|
"$languageDef" \
|
|
'%%% No changes may be made beyond this point.
|
|
|
|
\uselanguage {USenglish} %%% This MUST be the last line of the file.'
|
|
}
|
|
|
|
tlutils_create_language_lua () {
|
|
tlutils__create_config_files \
|
|
"$texmfdist"/tex/generic/config/language.us.lua \
|
|
"$TEXMFSYSVAR"/tex/generic/config/language.dat.lua \
|
|
'-- Generated by nixpkgs' \
|
|
"$languageLua" \
|
|
'}'
|
|
}
|
|
|
|
tlutils_update_context_cache () {
|
|
if [[ -x $out/bin/mtxrun ]] ; then
|
|
tlutils_info "setting up ConTeXt cache"
|
|
|
|
# temporarily patch mtxrun.lua to generate uuid's deterministically from SOURCE_DATE_EPOCH
|
|
mv "$out"/bin/mtxrun.lua{,.orig}
|
|
substitute "$out"/bin/mtxrun.lua.orig "$out"/bin/mtxrun.lua \
|
|
--replace-fail 'randomseed(math.initialseed)' "randomseed($SOURCE_DATE_EPOCH)"
|
|
|
|
# this is very verbose, save the output for debugging purposes
|
|
{
|
|
mtxrun --generate
|
|
context --luatex --generate
|
|
[[ ! -x $out/bin/luajittex ]] || context --luajittex --generate
|
|
} >"$TEXMFSYSVAR"/context-cache.log
|
|
|
|
mv "$out"/bin/mtxrun.lua{.orig,}
|
|
fi
|
|
}
|
|
|
|
# init variables (export only the ones that are used in the wrappers)
|
|
export PATH="$out/bin:$PATH"
|
|
TEXMFSYSCONFIG="$out/share/texmf-config"
|
|
TEXMFSYSVAR="$out/share/texmf-var"
|
|
export TEXMFCNF="$TEXMFSYSVAR/web2c"
|
|
|
|
installtl_do_postinst_stuff
|