Pourquoi les Makefiles vous évitent de copier-coller les commandes GCC

6

Soyons honnêtes. Taper à la main de longues commandes de compilation gcc est pénible. La situation empire rapidement lorsque votre base de code s’agrandit, importe plusieurs bibliothèques et que vous modifiez constamment les choses. Vous vous retrouvez avec un cauchemar de copier-coller qui se brise si vous manquez un drapeau.

Entrez makefiles.

Ils existent pour une seule raison : vous empêcher de taper manuellement la même séquence de compilation, encore et encore. Au lieu de vous souvenir des indicateurs exacts et de l’ordre des fichiers objets, vous écrivez une recette. Ensuite, tapez simplement « make ».

Comment fonctionne réellement un Makefile

Vous commencez par créer un fichier littéralement nommé « makefile ». Aucune prolongation. Juste le nom. À l’intérieur, vous définissez les dépendances.

Voici une structure de base pour un petit projet C :

Notez l’indentation. C’est là que les débutants trébuchent. Cet espace avant « gcc » ? Il doit s’agir d’un caractère de tabulation. Pas huit espaces. Un onglet. Si vous utilisez des espaces, « make » générera une erreur énigmatique et vous passerez dix minutes à vous demander pourquoi votre syntaxe semble correcte à l’œil humain mais pas à la machine. Chaque ligne de commande sous une dépendance doit commencer par un onglet. Les définitions de dépendance elles-mêmes doivent être alignées à gauche. Aucune exception.

La logique des dépendances

Un makefile comporte deux types de lignes. Les premières sont les lignes de dépendance. Ceux-ci ressemblent à « cible : prérequis ».

main.o : main.c util.h

Cela se traduit par : “J’ai besoin de main.o. Pour l’obtenir, j’ai besoin de main.c et util.h.”

Le deuxième type est la ligne exécutable. Il se trouve sous la dépendance et commence par un onglet. C’est la commande qui s’exécute si make décide qu’elle doit être reconstruite.

Le système fonctionne sur un principe simple : si un fichier à droite des deux points est plus récent que le fichier à gauche, exécutez les commandes ci-dessous. Changer util.h ? make le voit, sait que main.o et util.o en dépendent et les reconstruit. Cela automatise la logique.

La règle cible

Il existe une règle d’or pour le haut de votre makefile. La première cible répertoriée est celle que « make » essaie de construire par défaut.

Dans l’exemple ci-dessus, « main » est la première ligne. Ainsi, lorsque vous exécutez « make » sans arguments, il construit l’exécutable final.

main : main.o util.o
gcc -o main main.o util.o

Si vous modifiez main.o, cela déclenche la reconstruction de main. Si vous modifiez main.c, cela déclenche main.o, qui déclenche ensuite main. C’est une réaction en chaîne. Vous n’êtes pas obligé de le gérer. Vous éditez simplement votre code source et exécutez make.

Et si je ne suis pas sous Unix ?

Si vous êtes sous Windows ou utilisez un IDE comme Visual Studio ou Xcode, vous ne verrez peut-être pas de « makefile » au sens traditionnel. Ne pas paniquer. Votre compilateur a probablement des fonctionnalités équivalentes.

Les environnements de développement intégrés ont souvent des systèmes de construction sous le capot. Recherchez « Configurations de construction » ou « Propriétés du projet ». Ils font la même chose : suivre les dépendances et recompiler uniquement ce qui a changé. Mais si vous vous en tenez à la ligne de commande, « make » est la norme.

Vue d’ensemble

Utiliser make n’est pas