Gestion des packages et des polices

Ce qui décide vraiment de la longévité d’une installation LaTeX, ce n’est pas d’avoir appris par cœur la liste des options de tlmgr, mais de savoir où placer un fichier. Affichez le chemin de recherche TEXMF : un marqueur !! précède certaines arborescences et pas d’autres. Il signifie « ne pas parcourir le disque ; consulter uniquement la base ls-R », et ces deux caractères déterminent si un fichier déposé à la main est trouvé immédiatement ou reste invisible jusqu’au passage de mktexlsr. Cette page traite de l’ajout et de la mise à jour de packages avec tlmgr, du partage des rôles entre l’arborescence personnelle TEXMFHOME et l’arborescence système TEXMFLOCAL, de l’installation manuelle depuis CTAN et de la gestion des correspondances de polices (updmap) — avec les valeurs mesurées sur une véritable installation TeX Live 2024.

Ajouter un package : comment fonctionne tlmgr install

La façon standard d’ajouter un package LaTeX tient en une ligne, tlmgr install <nom>, et ses dépendances suivent par défaut. On peut nommer les packages un à un ou tirer toute une collection comme collection-fontsrecommended. L’installation dans une arborescence système exige les droits d’administrateur (sudo tlmgr install … sous Unix, un shell élevé sous Windows). --no-depends écarte volontairement les dépendances ; --reinstall réécrit des fichiers devenus défectueux.

terminal
# Install a package; dependencies come along by default
tlmgr install siunitx
tlmgr install collection-fontsrecommended

# Skip dependencies, or overwrite a broken install
tlmgr install --no-depends siunitx
tlmgr install --reinstall siunitx

# A system-wide tree needs admin rights
sudo tlmgr install siunitx

Ce qui compte davantage en pratique, c’est le chemin qui mène du message d’erreur au nom du package. Devant un LaTeX Error: File siunitx.sty not found, déposer dans le dossier du manuscrit un .sty trouvé par un moteur de recherche est le pire des gestes. Séparez d’abord le nom de fichier du nom de package : le fichier est siunitx.sty, le package est siunitx — souvent identiques, souvent pas : tikz.sty se trouve dans le package pgf. tlmgr search --global --file répond à « quel package fournit ce fichier », et c’est là le pont. Si le nom n’est qu’à moitié en mémoire, tlmgr search --global <mot> ; pour savoir ce qu’est un package, tlmgr info <nom> imprime description, licence, taille et liste des fichiers.

terminal
# From "File siunitx.sty not found" to an installed package
kpsewhich siunitx.sty                      # is it already here?
tlmgr search --global --file siunitx.sty   # which package ships it?
tlmgr install siunitx                      # install it properly

# Half-remembered name, or curious about a package
tlmgr search --global siunit
tlmgr info siunitx

Un comportement facile à manquer : ni tlmgr install ni tlmgr remove ne rafraîchissent les liens symboliques des répertoires système comme /usr/local/bin. Si votre PATH pointe directement vers le répertoire bin de TeX Live, cela n’a jamais d’importance ; mais si vous utilisez tlmgr path add pour câbler les liens des exécutables, des pages man et des pages info, il faut relancer soi-même tlmgr path add après avoir installé un package apportant un nouvel exécutable (et tlmgr path remove après en avoir retiré un). Si la ligne de commande ne vous convient pas, TeX Live fournit aussi tlshell, une interface Tcl/Tk qui cherche, installe, supprime, met à jour en masse et change de dépôt depuis une fenêtre — et affiche le journal des commandes sous-jacentes, ce qui en fait une porte d’entrée douce vers tlmgr.

Mettre à jour : --self et --all vont de pair

Le geste standard tient en une ligne, tlmgr update --self --all : --self met à jour tlmgr lui-même, l’infrastructure, et --all tout le reste. Cet ordre n’est pas affaire de goût. Le manuel de tlmgr précise, à propos de --all, qu’il met à jour tous les packages installés sauf tlmgr lui-même, et que si des mises à jour de tlmgr existent, cela produit une erreur à moins de fournir aussi --force ou --self. Un tlmgr périmé s’arrête donc et exige de se remplacer d’abord. Donnez-lui les deux options et c’est exactement ce qu’il fait : il se met à jour, puis, en cas de succès, redémarre dans sa nouvelle version pour terminer le reste.

terminal
# The standard move: infrastructure first, then everything else
tlmgr update --self --all

# See what would change before committing to it
tlmgr update --list

# Update one package only
tlmgr update siunitx

Il est utile de savoir ce que cette mise à jour fait par ailleurs. Les packages retirés d’une collection côté serveur sont désinstallés automatiquement, et ceux nouvellement ajoutés à une collection que vous possédez sont installés automatiquement ; --list montre les deux avant de s’engager. La provenance dépend du réglage dépôt, par défaut la redirection automatique de miroirs de CTAN. Si la connexion est lente ou pour figer un miroir précis, basculez durablement avec tlmgr option repository ; pour une seule exécution, ajoutez --repository <url>. Des valeurs par défaut comme le format de papier relèvent aussi de tlmgr : tlmgr paper a4 passe tous les outils en A4 d’un coup (ou par programme, tlmgr dvips paper a4). tlmgr option show affiche les réglages courants d’un bloc.

terminal
# Where tlmgr fetches from, and other stored defaults
tlmgr option repository ctan          # automatic CTAN mirror redirection
tlmgr option repository https://example.org/CTAN/systems/texlive/tlnet
tlmgr option show

# Use a different mirror for one run only
tlmgr install --repository https://example.org/CTAN/systems/texlive/tlnet siunitx

# Paper size defaults are stored here too
tlmgr paper a4
tlmgr dvips paper a4

TEXMFHOME face à TEXMFLOCAL

Les fichiers que tlmgr ne gère pas — la classe d’une conférence, un style que vous avez écrit, un package téléchargé à la main depuis CTAN — vont à l’un de deux endroits : TEXMFHOME pour vous seul, TEXMFLOCAL pour toute la machine. Les deux sont explorés avant l’arborescence de la distribution (TEXMFDIST) : un fichier de même nom placé là l’emporte donc. Les emplacements réels varient ; mieux vaut les afficher que les supposer. Sur ce Mac, kpsewhich -var-value=TEXMFHOME renvoie /Users/wedd/Library/texmf — et non ~/texmf. Sous Linux, la valeur par défaut est ~/texmf, et c’est pourquoi suivre à la lettre un tutoriel Linux sur un Mac rend le fichier définitivement invisible. Ici, TEXMFLOCAL vaut /usr/local/texlive/texmf-local, et le point remarquable est qu’il se trouve hors du répertoire de l’année : ce que l’on y dépose survit donc au passage au millésime suivant.

terminal
# Never guess these paths - print them
kpsewhich -var-value=TEXMFHOME    # your own tree (differs on macOS and Linux)
kpsewhich -var-value=TEXMFLOCAL   # machine-wide tree, outside the year directory
kpsewhich -var-value=TEXMFDIST    # the distribution itself - do not edit by hand

# The whole search order, including the !! markers
kpsewhich -expand-path='$TEXMF'

Le choix est simple : les fichiers destinés à vos propres manuscrits vont dans TEXMFHOME ; ce que tout le monde doit avoir sur une machine partagée va dans TEXMFLOCAL. TEXMFHOME ne demande aucun droit d’administrateur et suit votre répertoire personnel lors d’une réinstallation. À l’intérieur, respectez la même disposition que la distribution (la TDS) : un style LaTeX se range sous tex/latex/. La vue d’ensemble de cette disposition relève de « Structure et chemins du répertoire TeX » ; en pratique, la hiérarchie de l’exemple ci-dessous suffit le plus souvent. Un avertissement : ne laissez pas une vieille copie d’un .sty dans le dossier du manuscrit. TeX explore d’abord le répertoire courant, si bien que la copie périmée continue de l’emporter même après une mise à jour par tlmgr — une panne très difficile à diagnostiquer.

terminal
# A personal class file, in the tree that belongs to you
HOME_TREE="$(kpsewhich -var-value=TEXMFHOME)"
mkdir -p "$HOME_TREE/tex/latex/local"
cp mythesis.cls "$HOME_TREE/tex/latex/local/"
kpsewhich mythesis.cls    # should print the path immediately

# Let tlmgr manage that tree too, with no root required
tlmgr init-usertree
tlmgr --usermode install siunitx

Quand mktexlsr et texhash sont vraiment nécessaires

La réponse est nette : c’est nécessaire quand un fichier a été déposé à la main dans TEXMFLOCAL ou une arborescence système, et inutile quand il l’a été dans TEXMFHOME. La raison tient au !! évoqué en ouverture. Développez TEXMF sur cette machine : !! précède /usr/local/texlive/texmf-local et texmf-dist, mais pas ~/Library/texmf. !! dit à kpathsea : « pour cette arborescence, ne regarde pas le disque ; ne fais confiance qu’à la base ls-R ». Donc tant que ls-R n’est pas régénérée, un fichier neuf n’existe pas. Corroboration : TEXMFDBS, la liste des arborescences dotées d’une ls-R, ne contient pas TEXMFHOME. Et cet index gagne son pain : texmf-dist/ls-R compte ici 276 953 lignes, ce qui évite à TeX de parcourir plus de 220 000 fichiers à chaque passe.

La commande qui reconstruit l’index est mktexlsr ; elle régénère ls-R pour chaque arborescence listée dans TEXMFDBS. texhash n’est pas une autre commande — vérification faite sur cette machine, texhash est un lien symbolique vers mktexlsr, donc littéralement le même programme sous deux noms. L’un ou l’autre convient. Comme elle écrit dans les arborescences système, elle demande sudo. Notez aussi que tlmgr et getnonfreefonts se chargent eux-mêmes du rafraîchissement : en pratique, le seul moment où on la tape, c’est après avoir copié des fichiers à la main.

terminal
# The same file in the system tree DOES need the index rebuilt
LOCAL_TREE="$(kpsewhich -var-value=TEXMFLOCAL)"
sudo mkdir -p "$LOCAL_TREE/tex/latex/local"
sudo cp mythesis.cls "$LOCAL_TREE/tex/latex/local/"
sudo mktexlsr          # texhash is a symlink to this same program

kpsewhich mythesis.cls # now it resolves
kpsewhich -all mythesis.cls  # and shows every copy, if several collide

Installer à la main depuis CTAN : .dtx et .ins

On ne procède à la main que pour ce que tlmgr n’a pas : une classe qu’une revue distribue elle-même, un package publié la semaine dernière, une version qui n’existe que sur le site de l’auteur. Certains packages CTAN livrent un simple .sty, mais beaucoup arrivent par paire — .dtx, qui réunit le source et sa documentation, et .ins, le fichier d’instructions qui l’extrait. tex foo.ins engendre alors foo.sty à partir du .dtx ; il ne reste qu’à le copier au bon endroit sous TEXMFHOME. Le format .dtx est la programmation lettrée à l’état pur : pdflatex foo.dtx produit un manuel PDF contenant le source commenté.

terminal
# A package that ships as .dtx + .ins: extract, then place
tex foo.ins                     # writes foo.sty (and foo.cls, if any)
pdflatex foo.dtx                # optional: build the annotated manual

HOME_TREE="$(kpsewhich -var-value=TEXMFHOME)"
mkdir -p "$HOME_TREE/tex/latex/foo"
cp foo.sty "$HOME_TREE/tex/latex/foo/"
kpsewhich foo.sty

Côté MiKTeX : mpm et l’installation automatique

MiKTeX ne possède pas de tlmgr. Sa ligne de commande est mpm (le MiKTeX Package Manager) et son interface graphique la MiKTeX Console ; mises à jour et ajouts de packages passent par là. La différence majeure est l’installation à la volée : un package que le document réclame et que vous n’avez pas est téléchargé en cours d’exécution, et la compilation continue (la Console permet de choisir : toujours installer, demander à chaque fois, jamais). Cette automatisation a toutefois une contrepartie : même lorsque MiKTeX est installé pour tous les utilisateurs, les packages récupérés à la volée atterrissent dans le AppData\Roaming de l’utilisateur qui exécute. Sur une machine partagée, installez plutôt d’avance ce dont vous avez besoin en mode administrateur.

Gérer les correspondances de polices : updmap et getnonfreefonts

Une correspondance de polices est une table ligne à ligne qui dit : « la police que TeX appelle sous ce nom est en réalité ce fichier, et voici comment l’intégrer au PDF ». Il y a pdftex.map pour pdftex et dvipdfmx, psfonts.map pour dvips, kanjix.map pour le japonais, et d’autres. On ne les écrit jamais à la main — c’est updmap qui les engendre. Pour l’ordre de grandeur, comptez les lignes : pdftex.map fait ici 45 443 lignes. Installer un package de polices et laisser tourner updmap, c’est ce qui met cette table à jour ; c’est seulement alors que la police peut être intégrée à un PDF.

updmap a deux visages — updmap-sys pour tout le système et updmap-user pour vous seul — et c’est là que se cache le piège le plus vicieux de la configuration de TeX Live. updmap --help en avertit lui-même : dès lors qu’updmap-user a été exécuté, ne serait-ce qu’une fois, exécuter updmap-sys n’a plus aucun effet. Un fichier de configuration personnel est créé et masque désormais celui du système. updmap-sys émet bien un avertissement dans ce cas, mais sans en connaître la cause on peut chercher très longtemps pourquoi un lancement en administrateur ne change rien. La règle sûre : n’utiliser qu’updmap-sys et ne jamais toucher à updmap-user.

L’intégration des polices japonaises, chinoises et coréennes possède sa propre porte d’entrée : kanji-config-updmap-sys. Il appelle updmap en dessous et permet de changer la famille de polices CJK intégrée aux PDF. Avec status, il indique l’état courant — sur cette machine, la famille japonaise actuelle est haranoaji, les familles disponibles étant haranoaji, ipa et ipaex. Autrement dit, les polices japonaises fournies dans TeX Live sont Harano Aji et IPA / IPAex, et Noto CJK et Source Han n’y figurent pas. Pour les employer, on pointe vers les polices installées dans le système d’exploitation, ou on les installe séparément.

terminal
# Ask, without changing anything: which CJK family is embedded?
kanji-config-updmap-sys status

# Switch the embedded Japanese family, machine-wide
sudo kanji-config-updmap-sys haranoaji

# Rebuild the map files after a manual font install
sudo updmap-sys        # never updmap-user: it permanently shadows updmap-sys

Pour finir, les polices qui ne peuvent pas voyager avec la distribution. Une police sous licence « libre d’usage mais non vendable » ne peut pas être intégrée à TeX Live, qui est aussi distribué sur un DVD mis en vente. Le script getnonfreefonts de TUG existe précisément pour cela : il récupère la police et ses fichiers de support TeX depuis CTAN et configure le tout pour que TeX les trouve. La clé est la distinction entre --user (vers TEXMFHOME) et --sys (vers l’arborescence système). La commande distincte getnonfreefonts-sys que l’on voit dans d’anciens textes n’existe plus — pour tous les utilisateurs de la machine, lancez getnonfreefonts --sys … avec les droits d’administrateur. --lsfonts énumère ce qui est proposé.

terminal
# See what is on offer, then install into your own tree
getnonfreefonts --user --lsfonts
getnonfreefonts --user luximono

# Or system-wide, for everyone on the machine
sudo getnonfreefonts --sys luximono
  • Installez les packages généraux avec tlmgr. Une copie périmée laissée dans le dossier du manuscrit continue de l’emporter après une mise à jour et produit des pannes que personne n’explique.
  • Les fichiers propres à un modèle de conférence peuvent résider dans le dépôt du manuscrit, car ils appartiennent au lot de soumission et non à la distribution.
  • Sur les machines partagées et en CI, consignez dans le README ou le .latexmkrc le millésime de TeX Live, les noms des packages ajoutés et tout dépôt ou tag Docker figé. « Je l’ai installé une fois sur mon portable » n’est pas de la reproductibilité.
  • Ne lancez pas tlmgr update --self --all juste avant une remise. Vous produiriez le PDF avec des packages différents de ceux de la veille. Essayez les mises à jour un autre jour.
  • N’utilisez jamais updmap-user. Un seul lancement suffit pour qu’updmap-sys n’ait plus aucun effet, et la cause est ensuite extrêmement difficile à repérer.