Ecrire des Makefiles pour BSD make ---------------------------------- iMil - 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/. prerequis --------- 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. 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 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 "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 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 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 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