9 janvier 2022
Résumé. Quand un projet atteint une certaine taille, il arrive qu’on puisse en isoler une “bibliothèque” (sous-projet) qu’on espère réutiliser dans d’autres projets. Ici on montre comment organiser et compiler un projet (en C) qui contient un sous-projet. Et surtout on explique les Makefile
s qui vont avec.
Dernière mise à jour : 9 janvier 2022.
Le programme principal suivant
// main.c
#include <stdio.h>
#include "MusicLib.h"
int main() {
"Pouet-Pouet.mp3");
music_play(
music_stop(); }
fait appel à deux fonctions d’un sous-projet “MusicLib”. Elles sont déclarées dans MusicLib.h
qui se trouve dans le répertoire du sous-projet.
Le Makefile
du projet principal
CFLAGS = -std=c11 -Wall -Wextra
CPPFLAGS = -IMusicLib/include
LDLIBS = -LMusicLib/lib/ -lmymusic
all: updates main
updates:
(cd MusicLib ; make)
main : main.o
clean:
$(RM) *~ *.o
mrproper: clean
$(RM) main
(cd MusicLib ; make mrproper)
réalise la fabrication de l’exécutable main
.
MusicLib.h
est pris dans MusicLib/include/MusicLib.h
;music_play()
et music_stop()
sont dans la bibliothèque statique MusicLib/lib/libmymusic.a
.Déroulement : si on lance la commande make
avec la cible par défaut (all
), le sous-projet est d’abord mis à jour pour produire éventuellement une nouvelle version de la bibliothèque MusicLib/lib/libmymusic.a
. Ensuite, le main
est fabriqué.
Attention si le main
existe déjà et est à jour par rapport à main.c
, il n’est pas recréé si la bibliothèque a été modifiée (on verra peut être plus loin comment arranger ça).
Le projet et le sous-projet sont organisés ainsi
.
|-- Makefile
|-- MusicLib
| |-- Makefile
| |-- include
| | |-- MusicLib.h
| | |-- music_play.h
| | `-- music_stop.h
| |-- lib
| |-- obj
| `-- src
| |-- music_play.c
| `-- music_stop.c
`-- main.c
5 directories, 8 files
Le fichier MusicLib/src/music_play.c
contient le source d’une fonction
#include <stdio.h>
#include "music_play.h"
void music_play(char *filename) {
"vous entendez maintenant %s\n", filename);
printf( }
dont l’entête est dans MusicLib/include/music_play.h
#ifndef MUSIC_PLAY_H
#define MUSIC_PLAY_H
void music_play(char *filename);
#endif
Même chose pour music_stop
. le fichier MusicLib/include/MusicLib.h
regroupe les entêtes “exportées” du sous-projet :
#ifndef MUSIC_LIB_H
#define MUSIC_LIB_H
#include "music_play.h"
#include "music_stop.h"
#endif
#
# Makefile pour le sous projet MusicLib
#
CFLAGS = -std=c11 -Wall -Wextra
CFLAGS += -MMD
CPPFLAGS = -Iinclude
ARFLAGS = rv
OBJ = music_play music_stop
lib/libmymusic.a: $(addprefix obj/,$(addsuffix .o,$(OBJ)))
$(AR) $(ARFLAGS) $@ $^
obj/%.o: src/%.c
$(COMPILE.c) -o $@ $<
/*.d)
-include $(wildcard obj
clean:
$(RM) *~ */*~ */*.d */*.o
mrproper: clean/*.a $(RM) lib
Si on exécute ce Makefile
, on voit passer les étapes de fabrication de la cible par défaut (lib/libmusic.a
) :
$ make
cc -std=c11 -Wall -Wextra -MMD -Iinclude -c -o obj/music_play.o src/music_play.c
cc -std=c11 -Wall -Wextra -MMD -Iinclude -c -o obj/music_stop.o src/music_stop.c
ar rv lib/libmymusic.a obj/music_play.o obj/music_stop.o
ar: création de lib/libmymusic.a
a - obj/music_play.o
a - obj/music_stop.o
à savoir
cc
) des fichiers obj/*.o
à partir des sources src/*.c
,ar
) de la bibliothèque à partir des obj/*.o
.Remarque : l’option -MMD
jointe à la directive -include
permet la gestion automatique des dépendances
Si on lance maintenant la commande make
dans le répertoire principal :
$ make
(cd MusicLib ; make)
make[1] : on entre dans le répertoire « /xxx/MusicLib »
make[1]: « lib/libmymusic.a » est à jour.
make[1] : on quitte le répertoire « /xxx/MusicLib »
cc -std=c11 -Wall -Wextra -IMusicLib/include -c -o main.o main.c
cc main.o -LMusicLib/lib/ -lmymusic -o main
main.c
est compilé ;Il ne reste plus qu’à l’exécuter
$ ./main
vous entendez maintenant Pouet-Pouet.mp3
fin de la musique
Ce qui est présenté ci dessus, c’est le makefile quand le sous-projet est encore instable, c’est à dire en cours de co-développement avec le projet principal.
Quand le sous-projet est stable, il est “sorti” de l’arborescence du projet, et le Makefile
du projet principal ne demande plus sa re-compilation.
.
|-- Makefile
|-- MusicLib
| |-- Makefile
| |-- include
| | |-- MusicLib.h
| | |-- music_play.h
| | `-- music_stop.h
| |-- lib
| | `-- libmymusic.a
| |-- obj
| | |-- music_play.d
| | |-- music_play.o
| | |-- music_stop.d
| | `-- music_stop.o
| `-- src
| |-- music_play.c
| `-- music_stop.c
|-- main
|-- main.c
`-- main.o
5 directories, 15 files