Articles

Qu’est ce qu’un Makefile et comment ça fonctionne?

Posted by admin

Si vous souhaitez exécuter ou mettre à jour une tâche lorsque certains fichiers sont mis à jour, le make utilitaire peut venir dans maniable. La balise make utilitaire nécessite un fichier, Makefile (ou makefile), qui définit un ensemble de tâches à exécuter. Vous avez peut-être utilisé make pour compiler un programme à partir du code source. La plupart des projets open source utilisent make pour compiler un binaire exécutable final, qui peut ensuite être installé en utilisant make install.,

Dans cet article, nous allons explorer make et Makefile utilisation de base et des exemples avancés. Avant de commencer, assurez-vous que make est installé dans votre système.

exemples

commençons par imprimer le classique « Hello World » sur le terminal. Créer un répertoire vide myproject contenant un fichier Makefile avec ce contenu:

say_hello:
echo "Hello World"

Maintenant, exécutez le fichier en tapant make dans le répertoire myproject., La sortie sera:

$ make
echo "Hello World"
Hello World

Dans l’exemple ci-dessus, say_hello se comporte comme un nom de fonction, comme dans tout langage de programmation. Cela s’appelle de la cible. Les prérequis ou dépendances suivent la cible. Par souci de simplicité, nous n’avons défini aucune condition préalable dans cet exemple. La commande echo "Hello World" s’appelle la recette. La recette utilise des conditions préalables pour faire une cible. La cible, les prérequis et les recettes forment ensemble une règle.,

Pour résumer, voici la syntaxe d’une règle générale:

target: prerequisites
<TAB> recipe

par exemple, une cible peut être un fichier binaire qui dépend de conditions préalables (fichiers sources). D’autre part, une condition peut également être une cible qui dépend d’autres dépendances:

Il n’est pas nécessaire pour que la cible soit un fichier; il pourrait être juste un nom pour la recette, comme dans notre exemple. Nous appelons ces « fausses cibles., »

pour revenir à l’exemple ci-dessus, lorsque make a été exécuté, la commande entière echo "Hello World" a été affichée, suivie de la sortie de la commande réelle. Souvent, nous n’en veux pas. Pour supprimer l’écho de la commande, nous avons besoin de commencer echo par @:

say_hello:
@echo "Hello World"

Maintenant, essayez d’exécuter make nouveau., La sortie devrait afficher seulement ceci:

$ make
Hello World

nous allons ajouter un peu plus de fausses cibles: generate et clean à la balise Makefile:

Si nous essayons d’exécuter make après les changements, seule la cible say_hello sera exécuté. En effet, seule la première cible du makefile est la cible par défaut. Souvent appelé objectif par défaut, c’est la raison pour laquelle vous verrez all comme première cible dans la plupart des projets., Il est de la responsabilité de all pour appeler d’autres cibles. Nous pouvons remplacer ce comportement en utilisant une cible bidon spéciale appelée .DEFAULT_GOAL.

nous allons l’inclure au début de notre makefile:

.DEFAULT_GOAL := generate

Cela va exécuter la cible generate comme valeur par défaut:

$ make
Creating empty text files...
touch file-{1..10}.txt

Comme son nom l’indique, le faux cible .DEFAULT_GOAL pouvez exécuter qu’une seule cible à la fois. C’est pourquoi la plupart des makefiles incluent all comme cible pouvant appeler autant de cibles que nécessaire.,

nous allons inclure le faux cible all et supprimer .DEFAULT_GOAL:

Avant d’exécuter make, citons un autre faux cible, .PHONY, où l’on définit toutes les cibles qui ne sont pas des fichiers. make exécutera sa recette indépendamment du fait qu’un fichier avec ce nom existe ou de l’Heure de sa dernière modification., Voici le makefile complet:

Le make devrait appeler say_hello et generate:

$ make
Hello World
Creating empty text files...
touch file-{1..10}.txt

C’est une bonne pratique de ne pas appeler clean dans un all ou le mettre comme première cible., clean devrait être appelé manuellement lorsque le nettoyage est nécessaire dans un premier argument de make:

$ make clean
Cleaning up...
rm *.txt

Maintenant que vous avez une idée de la façon dont un makefile de base fonctionne et comment écrire un makefile simple, regardons quelques exemples plus avancés.

exemples avancés

Variables

dans l’exemple ci-dessus, la plupart des valeurs cibles et prérequis sont codées en dur, mais dans les projets réels, elles sont remplacées par des variables et des modèles.,

la façon la plus simple de définir une variable dans un makefile est d’utiliser l’opérateur =., Par exemple, pour assigner la commande gcc pour une variable CC:

CC = gcc

il est également appelé une récursif étendue variable, et il est utilisé dans une règle comme indiqué ci-dessous:

hello: hello.c
${CC} hello.c -o hello

Comme vous l’aurez deviné, la recette se développe comme ci-dessous lorsqu’il est transmis au terminal:

gcc hello.c -o hello

les Deux ${CC} et $(CC) sont valables références pour appeler gcc. Mais si on essaie de réaffecter une variable à elle-même, cela provoquera une boucle infinie., Nous allons vérifier cela:

CC = gcc
CC = ${CC}
all:
@echo ${CC}

Exécution make résultat sera:

$ make
Makefile:8: *** Recursive variable 'CC' references itself (eventually). Stop.

Pour éviter ce scénario, nous pouvons utiliser la balise := opérateur (ce qui est aussi appelé simplement l’étendue de la variable). Nous ne devrions avoir aucun problème à exécuter le makefile ci-dessous:

CC := gcc
CC := ${CC}
all:
@echo ${CC}

Patterns and functions

le makefile suivant peut compiler tous les programmes C en utilisant des variables, des patterns et des fonctions., Explorons-le ligne par ligne:

Voici la réécriture du makefile ci-dessus, en supposant qu’il soit placé dans le répertoire ayant un seul fichierfoo.c:

Leave A Comment