La version originale de ce document se trouve a l'adresse http://imil.net/docs/BSD-Makefile.txt

Ecrire des Makefiles pour BSD make


iMil imil@gcu.info - 14 / 07 / 2004

Les systèmes BSD bénéficient d'un make(1) extremement puissant. En effet, ce dernier est capable, dans le cadre de l'interprétation d'un Makefile, de comprendre une syntaxe relativement complexe, et permet de ce fait une grande souplesse dans la portabilité des logiciels. La plupart des systèmes BSD (tous ?) ont tiré profit de ces possibilités pour mettre en place un système évolué d'inclusions de definitions pour permettre la création express de Makefile complexes. Nous n'aborderons dans cette doc que les aspects basiques de la construction de Makefile's BSD, pour plus d'infomations, reportez-vous a la man page de make(1), ainsi qu'à /usr/share/mk/bsd.README et l'ensemble des .mk situés dans /usr/share/mk/. Prérequis


Sous NetBSD, FreeBSD et OpenBSD, tout est fourni dans le système de base. Sous GNU/Linux, il vous faudra installer les BSD build utils, par exemple sous Debian: apt-get install freebsd-buildutils.

1. Un Exemple simple


Considérons le programme cible “bla”, constitué uniquement d'un fichier source “bla.c”. Le Makefile correspondant contiendra :

$ cat Makefile
PROG=	bla
 
.include <bsd.prog.mk>

La commande make(1) construira alors le programme “bla” en considérant toutes les options par defaut spécifiées par bsd.prog.mk et tous les fichiers .mk que ce dernier inclut lui même. Cela implique entre autres l'inclusion des parametres spécifiés dans votre /etc/mk.conf (NetBSD) ou /etc/make.conf (FreeBSD).

2. Sources multiples et directives de compilation


Vous avez découpé votre programme “bla” en 3 parties, bla1.c, bla2.c et bla3.c. Pour faire dépendre votre cible de ces 3 fichiers sources, vous allez utiliser la macro “SRCS” comme suit :

$ cat Makefile
PROG=   bla
SRCS=	bla1.c bla2.c bla3.c
 
.include <bsd.prog.mk>

“bla” nécessite un include situé à un endroit non standard, et de plus, vous souhaitez durcir les flags de compilation, il est temps d'inclure une macro CFLAGS :

$ cat Makefile
PROG=		bla
SRCS=		bla1.c bla2.c bla3.c
 
CFLAGS+=	-I../../bli/include -ansi -Wall -pedantic	\
		-Wall -Wmissing-prototypes -Wno-uninitialized	\
		-Wstrict-prototypes
 
.include <bsd.prog.mk>

Quelques explications s'imposent. Si vous ecriviez déja des Makefile's, vous connaissez sans doute la macro CFLAGS qui spécifie des directives de compilation des objects, ici il ne s'agit pas d'une simple affectation mais d'un ajout aux eventuelles directives précédemment affectées à CFLAGS, par exemple par d'autres fichiers .mk.

make(1) comprend plusieurs types d'affectations :

=	affecte une valeur à la variable, ecrasant toute valeur precedemment
	affectée

+=	ajoute une valeur aux valeurs presentes dans la variable

?=	affecte une valeur à la variable uniquement si cette dernière n'est pas
	déja definie

:=	affectation avec expension préalable de la valeur

!=	(très utile) affecte à la variable le resultat de l'execution de la
	valeur par le shell, exemple: OS!=	uname -s

3. Conditions et portabilité


En utilisant les opérateurs précedemment cités, on peut très facilement ecrire un Makefile portable, par exemple :

OS!=	uname -s
 
.if ${OS} == NetBSD || ${OS} == OpenBSD
LDADD+=		-lossaudio
DPADD+=		${LIBOSSAUDIO}
.endif

Comme on peut le voir dans cet extrait de Makefile, make(1) supporte les structures conditionnelles via une syntaxe très intuitive :

.if [!]expression [operateur expression ...]
	on fait quelque chose
.elif [!]expression [operateur expression ...]
	on fait autre chose
.else
	on fait encore autre chose
.endif

On peut, dans ces structures conditionnelles, utiliser les operateurs || (ou) et && (et).

La macro LDADD ajoute aux flags de linkage les flags spécifiés. La macro DPADD definit une dependance au programme, dans l'exemple precedent on ajoute une dependance sur la libossaudio

4. Sous-repertoires et librairies partagées


Notre programme d'exemple a grossi et son code source est maintenant organisé en plusieurs sous repertoires dont l'un contient les sources de la libbla, une librairie partagée ecrite pour l'occasion.

Le Makefile principal, celui qui va engendrer la compilation de toutes les briques du projet, est très simple :

$ cat Makefile
SUBDIR=		core network help libbla
 
.include <bsd.subdir.mk>

Un make(1) ira construire toutes les cibles des repertoires listés dans la macro SUBDIR.

Mais regardons de plus pres libbla/Makefile

$ cat libbla/Makefile
LIB=	bla
SHLIB_MAJOR=	1
SRCS=	bla.c bla1.c
 
.include <bsd.lib.mk>

L'inclusion de bsd.lib.mk aura pour effet de générer la libbla.so.1, ou le “1” provient de la macro SHLIB_MAJOR.

Pour utiliser cette librairie dans le source bla/core, il vous suffit d'ajouter dans bla/core/Makefile :

LDFLAGS+=	-L../libbla/libbla -lbla

Pour finir


Ce document n'a pas la prétention d'être exhaustif ou encore exempt d'erreurs, aussi si vous souhaitez y contribuer, n'hésitez pas à m'envoyer vos patchs / remarques à imil@gcu.info.

iMil

codaz/c/bsd_makefiles.txt · Last modified: 2010/01/12 13:29 (external edit)