User Tools

Site Tools


projtec:make

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
projtec:make [2016/09/19 11:34] – created orelprojtec:make [2024/03/18 15:06] (current) – external edit 127.0.0.1
Line 1: Line 1:
-====Makefile====+======Makefile======
  
 //Pour compiler automatiquement et efficacement un projet de programmation, le Makefile est une solution élégante.// //Pour compiler automatiquement et efficacement un projet de programmation, le Makefile est une solution élégante.//
Line 23: Line 23:
 CC=gcc                      # compilateur CC=gcc                      # compilateur
 CFLAGS=-Wall -g -std=c99    # options de compilation CFLAGS=-Wall -g -std=c99    # options de compilation
-LDFLAGS=-L. -lm             # options de link+LDFLAGS=                    # options de link 
 +LDLIBS=-lm                  # bibliothèques
 CPPFLAGS=                   # options de preprocessing CPPFLAGS=                   # options de preprocessing
  
Line 31: Line 32:
 # règle spécifique pour générer l'exécutable # règle spécifique pour générer l'exécutable
 toto: toto.o tutu.o tata.o toto: toto.o tutu.o tata.o
- $(CC) $^ -o $@ $(LDFLAGS)+        $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)
  
-# règle générique de compilation des fichiers C+# règle générique de compilation des fichiers C (implicite)
 %.o: %.c %.o: %.c
  $(CC) $(CFLAGS) -c $< -o $@  $(CC) $(CFLAGS) -c $< -o $@
Line 50: Line 51:
   * La variable %%$%%< représente la première dépendance.    * La variable %%$%%< représente la première dépendance. 
   * La cible .PHONY permet d'indiquer des cibles particulières qui ne sont pas des fichiers, comme par exemple //clean//.   * La cible .PHONY permet d'indiquer des cibles particulières qui ne sont pas des fichiers, comme par exemple //clean//.
 +
 +
 +Par ailleurs, il n'est pas nécessaire d'indiquer la règle générique "%.o: %.c" ici, car cette règle est implicite dans les Makefile !
  
 Pour fabriquer une cible particulière, on fait //make cible//. Par défault, l'appel à //make// fabrique la première cible (//all// dans notre exemple. Pour fabriquer une cible particulière, on fait //make cible//. Par défault, l'appel à //make// fabrique la première cible (//all// dans notre exemple.
Line 58: Line 62:
 gcc -Wall -g -std=c99 -c tutu.c -o tutu.o gcc -Wall -g -std=c99 -c tutu.c -o tutu.o
 gcc -Wall -g -std=c99 -c tata.c -o tata.o gcc -Wall -g -std=c99 -c tata.c -o tata.o
-gcc toto.o tutu.o tata.o -o toto -L. -lm+gcc toto.o tutu.o tata.o -o toto -lm
  
 $ make clean $ make clean
Line 64: Line 68:
 </code> </code>
  
-//Expliquer comment injecter automatiquement des dépendances complexes dans un Makefile grâce à l'option '-MM'de gcc.//+L'utilisation de la règle générique (implicitement ou pas) est pratique, mais elle ne prend pas en compte toutes les dépendances, comme les fichiers auxiliaires (*.h). Pour améliorer notre Makefile, il faut ajouter les règles de dépendance explicitement, comme ci-dessous. 
 + 
 +<code bash Makefile> 
 +# variable standard pour la compilation 
 +CC=gcc                      # compilateur 
 +CFLAGS=-Wall -g -std=c99    # options de compilation 
 +LDFLAGS=                    # options de link 
 +LDLIBS=-lm                  # bibliothèques  
 +CPPFLAGS=                   # options de preprocessing 
 + 
 +# cible principale (par défaut) 
 +all: toto 
 + 
 +# règle spécifique pour générer l'exécutable 
 +toto: toto.o tutu.o tata.o 
 +        $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS) 
 + 
 +# dépendances explicites 
 +toto.o: toto.c tata.h tutu.h 
 +tata.o: tata.c tata.h 
 +tutu.o: tutu.c tutu.h 
 + 
 +.PHONY: clean 
 +clean: 
 + rm -f *.o *~ toto 
 +</code> 
 + 
 +Plus d'info sur les régles implicites : https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules 
 + 
 +==== Pour aller un peu plus loin ==== 
 + 
 +L'écriture des dépendances peut être fastidieux dans un gros projet, on peut alors utiliser la commande "gcc -MM".  
 + 
 +<code bash> 
 +$ gcc -MM *.c 
 +toto.o: toto.c tata.h tutu.h 
 +tata.o: tata.c tata.h 
 +tutu.o: tutu.c tutu.h 
 +</code> 
 + 
 +Pour aller encore plus loin, on peut inclure les dépendances dans le Makefile, que l'on générère explicitement avec la cible dep. 
 + 
 +<code bash Makefile> 
 +# variable standard pour la compilation 
 +CC=gcc                      # compilateur 
 +CFLAGS=-Wall -g -std=c99    # options de compilation 
 +LDFLAGS=                    # options de link 
 +LDLIBS=-lm                  # bibliothèques 
 +CPPFLAGS=                   # options de preprocessing 
 + 
 +# cible principale (par défaut) 
 +all: toto 
 + 
 +# règle spécifique pour générer l'exécutable 
 +toto: toto.o tutu.o tata.o 
 +        $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS) 
 + 
 +.PHONY: clean dep 
 + 
 +# génération des dépendances 
 +dep: 
 + $(CC) -MM *.c > depends.txt 
 + 
 +clean: 
 + rm -f *.o *~ toto 
 + 
 +# inclusion des dépendances 
 +-include depends.txt 
 +</code> 
 + 
 +Dans ce cas, il faut commencer par faire "make dep" pour générer le fichier des dépendances, puis après on peut faire "make". Il faut penser à remettre à jour les dépendances avec "make dep" quand on ajoute de nouveaux fichiers ou que l'on modifie les //includes//
 + 
 +==== Pour aller encore plus loin ==== 
 + 
 +//Parler de Makefile recursif avec "make -C subdir" ; parler des fonctions %%$%%(wildcard *.c) ; etc.// 
 + 
 + 
 +<code bash Makefile> 
 +SOURCES  := $(wildcard *.c) 
 +INCLUDES := $(wildcard *.h) 
 +OBJECTS  := $(SOURCES:.c=.o) 
 +</code> 
 + 
 + 
 +==== Nota Bene ==== 
 + 
 +//Quelques astuces...//
  
 +  * @ suppresses the normal 'echo' of the command that is executed.
 +  * - means ignore the exit status of the command that is executed (normally, a non-zero exit status would stop that part of the build).
 +  * + means 'execute this command under make -n' (or 'make -t' or 'make -q') when commands are not normally executed. See also the POSIX specification for make and also §9.3 of the GNU Make manual.
  
 +Plus d'info : https://stackoverflow.com/questions/3477292/what-do-and-do-as-prefixes-to-recipe-lines-in-make
  
  
projtec/make.1474284886.txt.gz · Last modified: 2024/03/18 15:05 (external edit)