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 Makefiles qui vont avec.
Dernière mise à jour : 9 janvier 2022.
Le programme principal suivant
// main.c
#include <stdio.h>
#include "MusicLib.h"
int main() {
music_play("Pouet-Pouet.mp3");
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) {
printf("vous entendez maintenant %s\n", filename);
}dont l’entête est dans MusicLib/include/music_play.h
#ifndef MUSIC_PLAY_H
#define MUSIC_PLAY_H
void music_play(char *filename);
#endifMê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 $@ $<
-include $(wildcard obj/*.d)
clean:
$(RM) *~ */*~ */*.d */*.o
mrproper: clean
$(RM) lib/*.aSi 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