Make et makefile ou Makefile , souvent utiliser pour compiler un projet en langage c
cheatsheet
1. Pourquoi utiliser Make ?
Make automatise la compilation :
- Évite de retaper
gcc -o prog main.c utils.cà chaque fois - Ne recompile que les fichiers modifiés (gain de temps)
- Facilite la gestion des projets multi-fichiers
2. Syntaxe de base
cible: dépendances
commandes
Important : Les commandes doivent commencer par une tabulation (pas des espaces !)
il faut comprendre que pour faire la cible il faut la ou les dépendance sinon infaisable
Premier exemple simple
fichier : makefile ou Makefile (fichier texte)
hello: hello.c
gcc -o hello hello.c
comme indiqué la dépendance est d’avoir le fichier hello.c (source) pour pouvoir avoir hello (cible)
bruno@elliott:~/Works/langage_C/hello$ make
make: *** Aucune règle pour fabriquer la cible « hello.c », nécessaire pour « hello ». Arrêt.
bruno@elliott:~/Works/langage_C/hello$ ls
makefile
bruno@elliott:~/Works/langage_C/hello$ cat makefile
hello: hello.c
gcc -o hello hello.c
oui il manque le source !
/***********************/
/* Exemple: hello.c */
/***********************/
#include <stdlib.h>
#include <stdio.h>
int main ()
{
puts("Bonjour le monde \n");
return EXIT_SUCCESS;
}
bruno@elliott:~/Works/langage_C/hello$ cat hello.c
/********************************/
/* Exemple: hello.c */
/********************************/
#include <stdlib.h>
#include <stdio.h>
int main ()
{
puts("Bonjour le monde \n");
return EXIT_SUCCESS;
}
bruno@elliott:~/Works/langage_C/hello$ make
gcc -o hello hello.c
bruno@elliott:~/Works/langage_C/hello$ ls
hello hello.c makefile
bruno@elliott:~/Works/langage_C/hello$ make
make: « hello » est à jour.
bruno@elliott:~/Works/langage_C/hello$
Les variables automatique de make
- Variable Signification Exemple Valeur pour target: dep1 dep2
- $@ Nom de la cible $@ → target target
- $< Première dépendance $< → dep1 dep1
- $^ Toutes les dépendances $^ → dep1 dep2 dep1 dep2
- $? Dépendances plus récentes que la cible $? dep1 (si plus récent)
- $* Base du nom de fichier (sans extension) $* → file pour file.c dep1 (sans .c)
- $+ Toutes dépendances (avec doublons) $+ dep1 dep2 dep1
$@
correspond au nom de la cible ‘target’
$<
correspond à dépendance 1
$^
Toutes les dépendances $^ → dep1 dep2 dep1 dep2
$?
Dépendances plus récentes que la cible $? dep1 (si plus récent)
$*
Base du nom de fichier (sans extension) $* → file pour file.c dep1 (sans .c)
$+
Toutes dépendances (avec doublons) $+ dep1 dep2 dep1
Exemple de makefile classique (un peu passe partout)
#la cible (executable)
TARGET = test
#Makefile petit projet avec skeletonc
CFLAGS = -g -Wall -pedantic -ansi
#compilateur ici gcc
CC = gcc
DEB = gdb
#section pour avoir TARGET il faut TARGET.c et faire
$(TARGET): $(TARGET).c
$(CC) $< $(CFLAGS) -o $@
#avec edit on aura le source dans vi
edit: $(TARGET).c
vi $(TARGET).c
#on va lancer gdb avec l'executable
gdb: $(TARGET)
$(DEB) $(TARGET)
#on nettoie le projet
clean:
rm $(TARGET)
# fausses cibles (phony)
.PHONY: edit gdb clean
Exemple d’un petit projet
cptchaine.c
/********************************
* Projet : passage de chaine
* Auteur : Bogt
* Date : 28/11/2022
********************************/
#include <stdlib.h>
#include <stdio.h>
#include "malib.h"
int main (int argc, char **argv)
{
int letter_number;
letter_number=lg_chaine ("Bonjour le monde");
printf ("on a %d lettre(s) ou espace(s) dans cette chaine\n",letter_number);
return EXIT_SUCCESS;
}
malib.c
#include <stdio.h>
/* fonction lg_chaine */
int lg_chaine(char *chaine)
{
int nb_lettre;
nb_lettre=0; /* pas de lettre au départ de la fonction */
printf ("%s \n",chaine);
while (chaine[nb_lettre]!=0) /* 0 ou '\0' */
{
nb_lettre=nb_lettre+1; /* on a une lettre en plus dans la chaine */
}
return nb_lettre; /* retour du nombre de lettre */
}
malib.h (header)
#ifndef __malib__ #define __malib__ /* fonction lg_chaine */ int lg_chaine(char *chaine); #endif
makefile (version simple)
cptchaine: cptchaine.o malib.o
gcc -o cptchaine malib.o cptchaine.o -Wall -ansi -pedantic -g
cptchaine.o: cptchaine.c
gcc -c cptchaine.c -Wall -ansi -pedantic
malib.o: malib.c
gcc -Wall -ansi -pedantic -c malib.c
tarball:
tar -zcvf ../cptchaine.tar.gz cptchaine.c malib.c malib.h Makefile
clean:
rm *.o cptchaine
version améliorée
CC = gcc
CFLAGS = -Wall -ansi -pedantic -g
OBJ = cptchaine.o malib.o
TARGET = cptchaine
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
cptchaine.o: cptchaine.c
$(CC) -c $< -o $@ $(CFLAGS)
malib.o: malib.c
$(CC) -c $< -o $@ $(CFLAGS)
tarball:
tar -zcvf ../$(TARGET).tar.gz cptchaine.c malib.c malib.h Makefile
clean:
$(RM) $(OBJ) $(TARGET)
.PHONY: all clean tarball
