Blog pour un amateur du system embarqué.

La petite instruction de GNU Make

| C Make

Bien que je préfère utilser CMake pour compiler mon programme, il reste encore important de comprendre le principe de GNU Make.

L’objectif de GNU Make

L’objectif de GNU Make est de déterminer automatiquement quelles pièces d’un grand programme devoir être recompilées, et spécifier les commandes pour les recompiler. Le format est ainsi:

# Le premier foo est la cible, et foo.c est la condition préalable.
foo: foo.c
	gcc -o foo foo.c
# La recette, obligatoirement précédée par une caractère de tabulation.
  

La cible peut être un fichier exécutable, un fichier objet, ou un label. La condition préalable est les fichiers/répertoires nécéssaires pour compiler la cible. La recette est la combinaison de commandes pour compiler et lier la cible.

Les règles du jeu sont:

  • On compile tous les codes source afin de créer le fichier de cible lorsqu’il n’existe pas.
  • On renouvelle le fichier de cible lorsque les fichiers indiqués pas la condition préalable sont plus nouveaux que la cible. On doit seulement recompiler les codes source actualisés et alors relier au fichier de cible.
  • Si les fichiers en-tête sont modifiés, il faut récompiler les codes source qui les comportent et alors relier au fichier de cible.

Le réglage de variables

Il y a quatre façons pour créer ou modifier des variables.

  • VAR = VAL : VAR devient VAL lorsque VAL est une constante; si VAL est une autre variable, VAR change aussi bien que VAL change. Par exemple:
VAR1 = un
VAR2 = $(VAR1)

# obtiendra un
$(warning $(VAR2))

VAR1 = deux

# obtiendra deux
$(warning $(VAR2))

fake: 
	@echo "Do something"
  
  • VAR := VAL : VAR devient VAL lorsque VAL est une constante; si VAL est une autre variable, VAR ne change pas si VAL change, c’est-à-dire que la valeur de VAR n’est pas liée avec $(VAL).
VAR1 = un
VAR2 := $(VAR1)

# obtenira un
$(warning $(VAR2))

VAR1 = deux

# obtiendra un encore
$(warning $(VAR2))

fake: 
	@echo "Do something"
  
  • VAR ?= VAL : VAR devient VAL lorsque VAR n’est pas encore défini, sinon VAR ne change pas.
  • VAR += VAL : on ajoute VAL à VAR.
VAR1 = un

# obtiendra un
$(warning $(VAR2))

VAR1 += deux

# obtiendra un deux
$(warning $(VAR1))
fake: 
	@echo "Do something"
  

Il y a aussi plusieurs variables encastrées utiles:

  • $@ : Le nom de cible
  • $^ : tous les fichiers/dossiers dans la condition préalable
  • $< : Premièr fichiers/dossiers dans la condition préalable
  • $? : tous les fichiers/dossiers dans la condition préalable qui sont réactualisés

Les fonctions encastrées utiles

Ces fonctions encastrées sont souvent utilisées :

  • Montrer les message :
    • $(warning «Message») : Montrer le message «Message» d’avertissement avec le nombre de ligne correspondante.
    • $(error «Message») : Affirmer le message «Message» d’erreur avec le numéro de ligne correspondante, et puis terminer l’action de make.
  • Traitement de chaînes de caractères :
    • $(subst «from»,«to»,«text<>) : si on trouve «from» dans «text», «from» sera replacé par «to».
    • $(patsubst «pattern»,«replacement»,«text») : Pour toutes les chaînes de caractères dans «text», s’il y a quelconque avec la forme définie comme «pattern», il deviendra la forme définie comme «replacement» (par exemple : %.c, %.o, foo.c -> “foo.c” a la forme comme %.c, donc il deviendra “foo.o”).
  • $(shell «commande») : Commande de shell, exécuter le «commande» et montrer le résultat.

.PHONY

On défine les cibles avec .PHONY lorsqu’elles n’ont pas de condition préalable. Normalement on l’utilise afin de définer la procédure de:

  • make clean : Supprimer les fichiers creés par la procédure de la compilation.
  • make install : Copier les bibliothèque ou les fichiers exécutable aux répertoires propres.
.PHONY: clean
TARGET = hello

$(TARGET): $(TARGET).c
	$(CC) -o $@ $^

clean:
	rm -f $(TARGET)

Références