Accueil > LaTeX > Compilation en série > Introduction à make avec (Xe)LaTeX

Introduction à make avec (Xe)LaTeX

lundi 8 août 2011, par Maïeul

Le programme make est un outil utilisé par les développeurs. On peut également s’en servir lorsqu’on fait du (Xe)LaTeX, pour automatiser les compilations.

En effet, il est assez courant de devoir faire plusieurs compilations successives, avec différents compilateurs ((Xe)LaTeX, SplitIndex, Biber etc.). Ces compilations doivent s’effectuer dans un certain ordre, parfois se répéter (par exemple en cas de variation des ruptures de pages, pour avoir une table des matières toujours à jour) etc.

Le risque est grand d’en oublier. C’est pourquoi utiliser make pour automatiser cela est une bonne idée. Voici un petit tutoriel à ma sauce. Il vient compléter celui qui m’a appris à me servir de make ainsi qu’un autre plus généraliste.

Que les puristes me pardonnent : il y a ici quelques approximations, pour les besoins de la cause.

On consultera désormais l’article sur LaTeXmk, qui est plus efficace.

Principe

Make est un logiciel qui sert à transformer un ou plusieurs fichiers en un fichier final. Pour ce faire, il va se servir d’un fichier makefile qui indique le fichier final souhaité, les fichiers sources initiaux et l’ensemble des étapes nécessaire à la production du fichier final.

Make est installé par défaut sur la plupart des distributions Linux. Sur Mac, il faut installer les outils dévellopeurs. En revanche son installation est complexe sur Windows.

Premier pas

Soit le dossier contenant les fichiers :
 principal.tex
 principal.bib

Je souhaite obtenir le fichier principal.pdf en exécutant successivement :
 xelatex principal.tex
 biber principal
 xelatex principal.tex.
 xelatex principal.tex pour avoir un sommaire correspondant à la mise en page finale.

Je vais écrire les lignes suivantes dans un fichier makefile [1].

La première ligne indique que le fichier principal.pdf « dépend » de principal.tex et de principal.bib. Les lignes suivantes, qui doivent commencer par des tabulations, indique les commandes à exécuter pour produire le fichier. J’ai créé ainsi une règle de fabrication, nommée principal.pdf.

Lorsque dans mon terminal je tape (en étant situé dans le répertoire en question) : make principal.pdf, je vois les différentes compilation se succéder. À la fin je peux ouvrir mon fichier principal.pdf.
Si je retape make principal.pdf, j’obtiens :
make : `principal.pdf’ is up to date.

En effet, makefile voit que les fichiers principal.tex et principal.bib ont été modifiés plus anciennement que le fichier principal.pdf. Il en conclut que le fichier principal.pdf est à jour.

En revanche, si je m’amuse à modifier l’un de ces fichier, taper make principal.pdf me recommencerait le processus de compilation.

Généralisons

Supposons qu’à côté de mes deux fichiers, j’ai également les fichiers annexe.bib et annexe.tex et qu’à partir de cela, je souhaite obtenir un fichier annexe.pdf.

Je pourrais m’amuser à créer une règle pour annexe.pdf. Mais je pourrais très bien fabriquer un règle générique pour les fichiers .pdf

Dans la description de la règle, le %.pdf signifie « n’importe quel fichier finissant par .pdf ». Pour la suite % signifie « la partie variante du nom du fichier », autrement dit « ce qui se trouve avant le .pdf ».

Dans le contenu de la règle, le $* signifie « la partie variante du nom du fichier de destination ».

Autrement dit, j’ai produit ici l’équivalent de

Mais cela pourrait s’étendre à fichier titi.pdf dépendant de titi.tex et titi.bib.

Évidemment mes fichiers cibles peuvent aussi dépendre de fichiers situés dans d’autres dossiers. Chez moi, par exemple, ce sont les fichiers situés dans les dossiers contenu et inclure. On peut indiquer la dépendance aux dossiers en indiquant la dépendance aux fichiers qu’ils contiennent.

Une règle par défaut

Pour le moment, je suis obligé, si je veux produire les fichiers principal.pdf et annexe.pdf, de faire successivement make principal.pdf et make annexe.pdf.

On pourrait vouloir produire ces deux fichiers d’un coup. Pour ce faire je vais créer une règle spéciale nommée all, que je vais placer en tout premier. Comme cette règle doit produire ces deux fichiers, je vais lui indique qu’elle nécessite les fichiers principal.pdf et annexe.pdf. Le programme make ira chercher les règles correspondante à la production de ces fichiers.

Ma règle s’écrit dont simplement :

Seulement voilà : imaginons que pour une raison quelconque, j’ai un fichier all dans mon dossier. Dans ce cas make je risque d’avoir des conflits. Pour éviter cela, je vais indiquer une règle spéciale : .PHONY. Cette règle indique simplement que les fichiers dont elle « dépend » n’existent pas, mais qu’il s’agit en réalité de nom de règle.

J’écris donc :

Si je tape make all, le programme va bien me produire mes deux fichiers principal.pdf et annexe.pdf.

Si je met cette règle en premier, elle sera exécutée si aucune règle n’est appelée, en frappant simplement make.

Nettoyage

La compilation produit tout le temps des fichiers annexes. Il peut être utile d’avoir une règle pour les supprimer automatiquement. La plupart du temps cette règle est appelée clean. Comme c’est une règle spéciale, il faut que je l’ajoute à la règle .PHONY

Voici un exemple de règle clean

La commande rm est une commande terminal qui efface les fichiers listés. L’option -f permet de ne pas avoir de message d’erreur si on demande l’effacement de fichiers qui n’existent pas. Ici nous demandons l’effacement des fichiers se finissant [2] par .aux, .bcf, .log, .xml, .toc, .bbl, .blg, ainsi que les fichiers .aux se situant dans des dossiers.

Affichage de message finaux

Reprenons notre règle %.tex. On aimerait avoir un message, à la toute fin des compilations, nous indiquant s’il y a des références bibliographiques inconnues.

Pour ce faire nous allons lire dans le fichier .log final, pour rechercher les ligne contenant Citation xxx undefined. Nous allons pour cela utiliser un programme, généralement livré en standard sous MacOs X et Linux, appelé grep. Ce programme permet de rechercher dans des fichiers du texte, en utilisant des outils de joker, qu’on appelle « expression régulière ».

Allons y, cela nous donne

Ligne 7, nous affichons, grâce à la commande Terminal toto le message "Citations indéfinies :". Le @ sert à indiquer à make de ne pas afficher cette ligne [3].

Ligne 8, nous exécutons la commande grep. L’option -i permet de ne pas tenir compte de la casse. Nous recherchons dans le fichier .log tout les lignes contenant Citation suivi d’une série de n’importe quel caractère [4] suivi de undefined et nous les affichons. À défaut, nous affichons « Aucune ».

Évidemment on pourrait étendre cela aux tests des étiquettes de référence croisés : pour vérifier par exemple les étiquettes en double, ou celles inexistantes.

Cela donnerait

Le fichier makefile final

Au final, tout cela donne


[1Attention, il n’y a pas d’extension !

[2Le caractère * est un joker signifiant « chaîne de taille indéfinie contenant n’importe quel caractère », je renvoi à n’importe quelle introduction au terminal.

[3Pour mieux comprendre, vous pouvez essayer sans le @.

Messages

  • Un grand merci pour le tuto.
    Exactement ce qu’il faut pour les handicapés du cerveau comme moi.

    • Il n’y a pas de quoi.

      Je viens de corriger une erreur : il faut supprimer le paragraphe

      Mais la particularité de la règle all est qu’il n’est pas besoin de l’appeler pour l’exécuter : c’est la règle exécutée par défaut si aucune règle n’est précisée. Ainsi frapper dans le Terminal make est équivalent à frapper make all.

      et le remplacer par

      Si je met cette règle en premier, elle sera exécutée si aucune règle n’est appelée, en frappant simplement make.

    • Pour les handicapés du cerveau paresseux, il y a latexmk, dispo dans TeXlive, et qui gère tout ça sans avoir besoin d’écrire un makefile :p

      Voir en ligne : http://people.untyped.org/damien.pollet

    • oui sans doute, mais la doc de latexmk est en anglais, tandis que le tuto sur lequel je m’étais basé était en français ;-)

      Je connaissais pas, faudrait que je creuse, et que je vois ce qu’il en est. Par exemple je vois que cela peut fonctionner avec Biber et pas BibTex. Par contre apparement faut faire des réglages pour avoir XeLaTeX et pas LaTeX. De même à voir aussi pour les indexs.

      En tout cas c’est assez intéréssant et à creuser.

    • Une occasion de faire un article en français sur le sujet :) Personnellement je recommande chaudement, c’est vrai qu’il faut parcourir la doc pour voir comment changer de compilateur, mais c’est pas sorcier. Comme point de départ tu peux piquer mon fichier de config (en anglais aussi). Par exemple pour mon essai de biblatex j’ai simplement fait \usepackage[backend=biber]{biblatex} et ça a été détecté tout seul sans rien faire d’autre.

      Pour revenir à make, quitte à écrire les scripts de compilation à la main, je le ferais avec un outil plus récent (genre Rake) qui est tout de même moins abscons que make…

    • yep, je regarderais cela.

      Pour le coup Biber il le détecte automatiquement car c’est mentionné dans le fichier bbl.

      Je ne connaissais pas Rake. C’est intéressant aussi. A voir donc. Mais effectivement cela doit considérablement simplifié certaines choses.

      Ceci dit j’aime bien mon système qui m’analyse automatiquement les log pour voir s’il y a des problèmes dans la biblio. A creuser donc.

    • Allez, hop, j’ai appris latexmk et fait un premier tutoriel : Introduction à Latexmk pour faciliter les compilations

Un message, un commentaire ?

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)