Différences entre les versions de « GNU make »

De Wikip
toross>WikiAdmin
m (1 version importée)
 
(Aucune différence)

Version actuelle datée du 26 décembre 2023 à 11:27

Version : 1.36.1 4519 (2023-12-26) 20231226112722

1 Le principe

§-1

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

exa-1
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
Attention16.png
Nous devrions utiliser les variables pour la liste dupliquée (inutilement et source d'erreurs) main.o kbd.o ...
exa-2

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
Attention16.png
la cible clean doit être déclarée PHONY (fausse cible -> n'est pas un fichier)
exa-3

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

exa-4

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

exa-5

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 $@ $<

https://www.gnu.org/software/make/manual/make.html#Implicit-Rules

Al3
Attention16.png
La partie droite (prerequisite) doit être vide sinon l'interprétation change du tout au tout:
exa-6
.c.o: foo.h
        $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
exa-7

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

exa-8

Ainsi la première règle↬exa-5 implicite en pattern rule serait :

%.o: %.c
        $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
exa-9

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

§-2

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

exa-10

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
exa-11

On obtient par exemple la règle pour les sources dans le langage C :

OUTPUT_OPTION = -o $@
# …
.c.o:
	$(COMPILE.c) $(OUTPUT_OPTION) $<
exa-12

On obtient par exemple la règle pour les sources dans le langage c++ :

OUTPUT_OPTION = -o $@
# …
.cpp.o:
	$(COMPILE.cpp) $(OUTPUT_OPTION) $<
exa-13

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

§-3

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

exa-14

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" $?

6 Liens