Différences entre les versions de « GNU make »
toross>WikiAdmin |
m (1 version importée) |
(Aucune différence)
|
Version actuelle datée du 26 décembre 2023 à 11:27
1 Le principe
La structure d'un fichier Makefile est une suite de règles. Chaque règle a la structure suivante :
target1 target2 ... : prerequisite1 prerequisite2 ..
recipe1
recipe2
...
☞ … https://www.gnu.org/software/make/manual/make.html#Rule-Introduction
2 Un exemple simple
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
2.1 Les variables
Al1 |
Nous devrions utiliser les variables pour la liste dupliquée (inutilement et source d'erreurs) main.o kbd.o ... |
Ce qui nous conduit à :
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
...
clean :
rm edit $(objects)
☞ … https://www.gnu.org/software/make/manual/make.html#Variables-Simplify
2.2 Les fausses (PHONY) cibles
Al2 |
la cible clean doit être déclarée PHONY (fausse cible -> n'est pas un fichier) |
Ce qui nous conduit à :
.PHONY : clean
clean :
rm edit $(objects)
☞ … https://www.gnu.org/software/make/manual/make.html#Cleanup
3 Les règles implicites
3.1 Les règles implicites fournies par make
Dans la règle suivante foo.o bar.o n'ont pas de règles de construction. Dans ce cas make va chercher dans les règles implicites.
foo : foo.o bar.o
cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)
3.2 Suffix rules
Parmi les règles implicites, il y a celles qui sont fournies par make, dont voici un exemple avec l'ancienne manière de l'écrire (Suffix rules) :
.c.o:
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
où
- $(CC) est le compilateur par défaut du langage C.
- $@ est une variable automatique(☞ … https://www.gnu.org/software/make/manual/make.html#Automatic-Variables) désignant la cible, exemple foo.o
- $< est une variable automatique désignant la source, exemple foo.c
☞ … https://www.gnu.org/software/make/manual/make.html#Implicit-Rules
Al3 |
La partie droite (prerequisite) doit être vide sinon l'interprétation change du tout au tout: |
.c.o: foo.h
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
Dans ce cas la la cible est .c.o est donc la règle n'est pas implicite, pour décrire une telle règle implicite il faut utiliser la nouvelle façon, pattern rules :
%.o: %.c foo.h
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
3.3 Pattern rules
Ainsi la première règle↬exa-5 implicite en pattern rule serait :
%.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
ou
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
☞ … https://www.gnu.org/software/make/manual/make.html#Static-Pattern
3.4 Les règles implicites par défaut
On obtient la liste des règles par défaut en exécutant la commande suivante dans un répertoire ne contenant pas de fichier Makefile :
make -p
☞ … https://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
On obtient par exemple la liste des suffixes :
.SUFFIXES: .out .a .ln .o .c .cc .C .cpp .p .f .F .m .r .y .l .ym .yl .s .S .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo .w .ch .web .sh .elc .el
On obtient par exemple la règle pour les sources dans le langage C :
OUTPUT_OPTION = -o $@
# …
.c.o:
$(COMPILE.c) $(OUTPUT_OPTION) $<
On obtient par exemple la règle pour les sources dans le langage c++ :
OUTPUT_OPTION = -o $@
# …
.cpp.o:
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
On obtient par exemple pour lier les fichiers binaires compilés :
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
# …
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
3.5 Annulation d'une règle implicite par défaut
On réécrit la règle sans fournir la recette :
%.o : %.c
☞ … https://www.gnu.org/software/make/manual/make.html#Canceling-Rules
4 Un autre style
En utilisant les règles implicites on peut écrire plusieurs cibles pour un seul source :
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h
☞ … https://www.gnu.org/software/make/manual/make.html#Combine-By-Prerequisite
5 Un cas presque générique : listes sources et objets/temporaires entièrement fabriquées : wildcard & patsubst
Ici la commande echo peut être remplacée par des commandes de compilation/transformations en 2 étapes :
- txt(s) -> html(s)
- html(s) -> index.html
Un répertoire tmp est crée localement pour les fichiers intermédiaires qui sont les html(s).
txtFiles=$(wildcard *.txt)
.PHONY: $(txtFiles)
tmpDir=tmp
tgts=$(patsubst %.txt,$(tmpDir)/%.html,$(txtFiles))
all : index.html
index.html : $(tgts) $(tmpDir)
$(tmpDir) : $(tgts)
mkdir -p $(tmpDir)
$(tmpDir)/%.html : %.txt
@echo "one" $?