## Projet Qualif ## Makefile de sous-répertoire. ## Copyright 2002, Thomas Tempé ## TODO: LICENCE ## ## V. 1.0, le 28/10/2002 par Thomas Tempé ## V. 2.0pre3, le 14/11/2002 par Thomas Tempé ## #La première règle est la règle par défaut all: images sousrepertoires cibles ############################################################ ############################################################ #### A configurer : #### #### #### ## NOTE : ## Dans la plupart des situations (compiler du C/C++ ou du LaTeX), ## le makefile détermine automatiquement ce qu'il a à faire. ## Vous n'aurez à modifier ce fichier que très rarement. ## Liste des cibles (fichiers finaux à compiler) ## séparées par des espaces ## exemple : ## CIBLES = mon_programme mes_tests ## Note : les fichiers squelette Qualif sont détectés ## automatiquement. CIBLES = ## Si une cible dépend de plusieurs fichiers, ## ajouter une règle comme celle-ci : ## ## resultats_tests.txt : programme test_donnees.txt ## ./programme < test_donnees.txt > resultats_tests.txt ## ## Note: pour les fichiers *.c, *.cpp et *.tex, ## les dépendances sont calculées automatiquement. #### #### #### Fin de la configuration #### ############################################################ ############################################################ help: @echo ' ' @echo ' INTRODUCTION ' @echo ' ' @echo ' Ce Makefile fait partie du projet Qualif. ' @echo ' ' @echo ' Il compile automatiquement les fichiers LaTeX qui contiennent ' @echo ' la commande "<>" dans les 10 premières lignes ' @echo ' (par exemple, les templates Qualif). ' @echo ' ' @echo ' Il compile automatiquement les sous-répertoires qui contiennent ' @echo ' eux-mêmes un fichier Makefile.' @echo ' ' @echo ' Il détermine automatiquement les dépendances des ' @echo ' fichiers latex et C/C++. ' @echo ' ' @echo ' Il propose les commandes courantes que l'on peut attendre d'un ' @echo ' Makefile: ' @echo ' "make" ou "make all" compile tout ' @echo ' "make " compile ce fichier ' @echo ' "make sousrepertoires" execute make récursivement ' @echo ' "make " execute make dans 1 seul sous-répertoire ' @echo ' "make cibles" compile juste le contenu de ce sous-répertoire ' @echo ' "make clean" nettoie le répertoire et les sous-répertoires ' @echo ' "make cleancourant" nettoie juste ce répertoire ' @echo ' ' info: help aide: help ## Les variables suivantes sont souvent définies par défaut, ## mais vous voudrez peut-être les modifier. ##Pour compatibilité SHELL = /bin/sh ##La liste des suffixes qui peuvent être sujet à des ##règles implicites #.SUFFIXES: #.SUFFIXES: .c .o .tex .dvi .ps .png .jpg .gif .dia ##Les paramètres de compilation pour le C/C++ peuvent ##être spécifiés une fois pour toutes ici CFLAGS = -g ############################################################ ## Les commentaires entre parenthèse sont les noms en anglais ## des fonctionnalités de Make utilisées ## tapez "info make" pour en savoir plus. ## Recherche les sous-répertoires contenant un Makefile, ## exclut le répertoire "SQUELETTE" #SOUSREPERTOIRESMAKE := $(wildcard */Makefile) $(wildcard */makefile) $(wildcard */MAKEFILE) #SOUSREPERTOIRES := $(dir $(SOUSREPERTOIRESMAKE)) SOUSREPERTOIRES := $(shell find -iname makefile|sed -e "s/\/Makefile$$//" -e "s/^\.\///" -e "s/^\.$$//" -e "s/^SQUELETTES$$//" | tr "\n" " ") sousrepertoires: $(SOUSREPERTOIRES) $(SOUSREPERTOIRES): $(MAKE) -C $@ ##Contient la liste de tous les fichiers à partir desquels on ##détermine automatiquement les dépendances ("wildcards", "the two flavours of variables") ##Pour chacun, on fabriquera un fichier .d SOURCESC := $(wildcard *.c) SOURCESCPP := $(wildcard *.cpp) SOURCESTEX := $(wildcard *.tex) SOURCESDEP := $(SOURCESC:.c=.d) $(SOURCESCPP:.cpp=.d) $(SOURCESTEX:.tex=.d) ## Inclure l'ensemble des fichiers "*.d" comme autant ## de petits morceaux de makefile. ("Automatic Prerequisites" ) include $(SOURCESDEP) ##Pour construire les cibles cibles: $(CIBLES) ciblesauto ##Ces cibles son déterminées automatiquement, ##parce qu'elles contiennent le marqueur "<>" ## ##Par défaut, on ne cherche que les fichiers .tex, .c, et .cpp ## ##Note : sur GNU grep, on peut utiliser les options "-s" et "-s", ##qui évitent l'affichage de messages d'erreur déroutants du style ## "fichier *.c non trouvé"; ##mais ces options ne fonctionnent pas sur d'autres versions de grep. CIBLESAUTOTEX := $(shell grep -lF "<>" *.tex) CIBLESAUTOCPP := $(shell grep -lF "<>" *.cpp) CIBLESAUTOC := $(shell grep -lF "<>" *.c) CIBLESAUTO := $(CIBLESAUTOTEX:.tex=.pdf) $(CIBLESAUTOCPP:.cpp=) $(CIBLESAUTOC:.c=) ciblesauto: $(CIBLESAUTO) ##Pour construire toutes les images IMAGESPNG := $(wildcard *.png) IMAGESJPEG:= $(wildcard *.jpg) IMAGESDIA := $(wildcard *.dia) IMAGESGIF := $(wildcard *.gif) IMAGES := $(IMAGESPNG:.png=.eps) $(IMAGESJPEG:.jpg=.eps) $(IMAGESDIA:.dia=.eps) $(IMAGESGIF:.gif=.eps) images: $(IMAGES) ############################################################ ## Règles implicites ("implicit rules", "chained rules") ## ## Ces règles déterminent de manière générale comment compiler certains ## types de fichiers. ## ## Make connaît déjà les règles génériques pour un certain nombre de ## formats de fichiers, par exemple les .cpp et les .o. ("catalogue of rules") %.pdf: %.ps ps2pdf $< %.ps: %.dvi dvips -o $@ $< %.dvi: %.tex #On compile plusieurs fois pour s'assurer que les #références croisées sont bien à jour #On redirige /dev/null vers l'entrée pour éviter d'avoir un prompt #et de devoir quitter manuellement latex $< < /dev/null latex $< latex $< %.eps: %.dia #Convertir en eps un fichier réalisé avec Dia. dia --export=$@ --nosplash $< %.eps: %.png #Convertir en eps une image png pngtopnm $< | pnmtops -rle -noturn -width 5.9 > $@ %.eps: %.jpg #Convertir en eps une image jpeg jpegtopnm $< | pnmtops -rle -noturn -width 5.9 > $@ %.eps: %.gif #Convertir en eps une image gif giftopnm $< | pnmtops -rle -noturn -width 5.9 > $@ %.d: %.c #Génère automatiquement un fichier .d contenant toutes les dépendances #introduites par les #include C et C++ #C'est facile, parce que le compilateur C offre cette fonctionalité $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ rm -f $@.$$$$ %.d: %.cpp #Idem pour les .cpp $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ rm -f $@.$$$$ %.d: %.tex #idem pour les .tex, #sauf que là, la fonctionalité n'existe pas : on est obligé de tout faire à la main. @echo "Recherche automatique des dépendances de $< ..." @perl -e $(PARSEUR_LATEX) $* < $< > $@ ############################################################ ## Autres règles utiles ## ## La présence de certaines règles est recommandée ## par les guides de style GNU. cleancourant: #supprime les fichiers temporaires du répertoire courant #le préfixe "-" évite que Make ne s'arrête si rm retourne une erreur -rm -f *~ *.aux *.log *.dvi *.log *.bak *.out *.toc *.o \#* *.d .log *.orig *.rej #supprime les images générées par make : -rm $(IMAGES) -rm TAGS -rm $(REPCOURANT)_*.tar.gz -find -name \*~ -o -name .\#\* \*.rej \*.orig VERSION.auto.txt|xargs rm #Nettoie le répertoire courant et tous ses sous-répertoires. clean: cleancourant -for rep in $(SOUSREPERTOIRES) SQUELETTE; do \ $(MAKE) -C $$rep clean;\ done distclean: cleancourant #Nettoie tout, y compris les répertoires "auto" (générés par #le mode AUC-tex de Emacs), CVS, et les cibles -for rep in $(SOUSREPERTOIRES); do \ $(MAKE) -C $$rep distclean;\ done -rm -rf auto CVS .xvpics -rm -f $(CIBLES) $(CIBLESAUTO) mostlyclean: cleancourant #Nettoie tout sauf "CVS" -for rep in $(SOUSREPERTOIRES); do \ $(MAKE) -C $$rep mostlyclean;\ done -rm -rf auto -rm -f $(CIBLES) $(CIBLESAUTO) maintainer-clean: distclean @echo 'This command is intended for maintainers to use; it' @echo 'deletes files that may need special tools to rebuild.' TAGS: #Cette commande construit une table de références #qui peut être utilisée par Emacs ou Vi etags `find -name \*.tex -or -name \*.c -or -name \*.cpp -or -name \*.h` REPCOURANT := $(shell pwd | tr "/" "\n"|tail -n 1) DISTDATE := $(shell date -I |tr -d "-") dist: #Crée une archive qui contient tout le répertoire courant, #nettoyé (pour la distribution du projet) -rm $(REPCOURANT)_*.tar.gz mkdir ../tmp.$$$$ ; \ cp -a ../$(REPCOURANT) ../tmp.$$$$ ; \ $(MAKE) -C ../tmp.$$$$/$(REPCOURANT) distclean ; \ rm -rf ../tmp.$$$$/$(REPCOURANT)/exemple ;\ rm -rf ../tmp.$$$$/$(REPCOURANT)/DOCUMENTATION ;\ rm -rf ../tmp.$$$$/$(REPCOURANT)/essais ;\ echo -e "Cette archive de " $(REPCOURANT) " a été réalisée à l'aide du Makefile de Qualif \n(http://gpl.insa-lyon.fr/QualifWiki) par " `whoami` " sur l'ordinateur " `hostname` " le :\n" `date +"%A %d %B à %R"` > ../tmp.$$$$/$(REPCOURANT)/VERSION.auto.txt; \ echo -e "La dernière invocation de 'make dist' été effectuée par " `whoami` " sur l'ordinateur " `hostname` " le :\n" `date +"%A %d %B à %R"` > VERSION.auto.txt; \ tar -zcvf $(REPCOURANT)_$(DISTDATE).tar.gz -C ../tmp.$$$$ $(REPCOURANT) ; \ rm -rf ../tmp.$$$$ qualifdist: #Crée une archive qui contient tout le répertoire courant, #non nettoyé (pour la distribution du squelette Qualif) -rm $(REPCOURANT)_*.tar.gz mkdir ../tmp.$$$$ ; \ cp -a ../$(REPCOURANT) ../tmp.$$$$ ; \ $(MAKE) -C ../tmp.$$$$/$(REPCOURANT) distclean ; \ echo -e "Cette archive du squelette de projet Qualif \n(http://gpl.insa-lyon.fr/QualifWiki)\n a été réalisée par " `whoami` "\nle :" `date +"%A %d %B à %R"` > ../tmp.$$$$/$(REPCOURANT)/VERSION.auto.txt; \ echo -e "La dernière distribution de Qualif à partir de ce répertoire a été effectuée le :\n" `date +"%A %d %B à %R"` > VERSION.auto.txt; \ tar -zcvf $(REPCOURANT)_$(DISTDATE).tar.gz -C ../tmp.$$$$ $(REPCOURANT) ; \ rm -rf ../tmp.$$$$ ##règles ne correspondant à aucun fichier à construire ("phony targets") .PHONY: clean all cleancourant distclean sousrepertoires $(SOUSREPERTOIRES) \ images ciblesauto install dist maintainer-clean mostlyclean ############################################################ ##Ce programme en Perl analyse un fichier .tex pour déterminer les ##autres fichiers dont il dépend. ## ##Si le .tex ne contient pas de "\begin{document}", ce n'est pas un ##fichier principale : on ne traite pas ses dépendances. Sinon, on ## l'analyse, enlevant les commentaires et retours chariot ## ($latex_sans_commentaires), et on commence par extraire la liste ## des autres .tex qu'il référence ($inclusion_tex). On les analyse de ## même tour à tour (@inclusions_a_proceder, $fichier_suivant). Ce ## faisant, on dresse la liste des dépendances .tex du fichier ## original ($toutes_inclusions_tex), et on constitue un bloc de ## données avec le contenu de l'ensemble de ces fichiers ## ($texte_integrale). Une fois ce travail terminé, on recherche dans ## ce bloc les inclusions d'images, dont on dresse la liste ## ($inclusion_img) Enfin, on écrit l'ensemble des dépendances (images ## et .tex) du fichier original. ## Le caractère ³ sert de délimiteur entre la partie traitée et non ## encore traitée des fichiers PARSEUR_LATEX = \ '@fichier=; \ $$_ = join("", @fichier);\ if ( /<>/ ){ \ do { \ $$latex_sans_commentaires = " ³ "; \ for $$_ (@fichier) { \ chomp; s/\\\%//; s/\\\n//; s/\%.*//; \ $$latex_sans_commentaires = "$$latex_sans_commentaires $$_"; \ } \ $$texte_integrale = " : $$texte_integrale $$latex_sans_commentaires"; \ $$inclusion_tex = $$latex_sans_commentaires; \ while( $$inclusion_tex =~ s/(.*?)³.*?\\(input|include) *(\[.*?\])? *\{(.*?)(.tex)? *\}/$$1 $$4.tex³/ ){\ }\ $$inclusion_tex =~ s/(.*?)³.*/$$1/; \ $$toutes_inclusions_tex = "$$inclusion_tex $$toutes_inclusions_tex";\ ($$fichier_suivant, @inclusions_a_proceder) = ( split(" ", $$inclusion_tex), @inclusions_a_proceder);\ if ($$fichier_suivant ne "") { \ open( INFILE, $$fichier_suivant );\ @fichier = ;\ }\ } while ($$fichier_suivant ne "");\ $$inclusion_img = " ³ $$texte_integrale"; \ while( $$inclusion_img =~ s/(.*?)³.*?\\includegraphics *(\[.*?\])? *\{(.*?)(.eps|.ps)? *\}/$$1 $$3.eps³/ ){\ } \ $$inclusion_img=~ s/(.*?)³.*/$$1/; \ print "$*.dvi: $$toutes_inclusions_tex $$inclusion_img \n\n";\ print "$*.d: $$toutes_inclusions_tex\n\n";\ }'