Cours CMP1 du jour
This commit is contained in:
parent
96e4f76a9c
commit
57289c0786
185
cmp/20120130.tex
Normal file
185
cmp/20120130.tex
Normal file
@ -0,0 +1,185 @@
|
||||
\chapter{Development Tools}
|
||||
|
||||
\section{AutoTools}
|
||||
|
||||
On va écrire une description du makefile que l'on veut obtenir.
|
||||
|
||||
\subsection{AutoMake}
|
||||
|
||||
On crée la première règle bin_PROGRAMS, puis le/les noms des programmes que
|
||||
l'on veut générer. Il s'agit d'une variable primaire.
|
||||
hello-world sera installé dans bin/ avec make install. On peut changer le
|
||||
prefix pour envoyer le fichier ailleurs.
|
||||
|
||||
Automake n'est cependant pas capable de compiler le programme, il a besoin
|
||||
d'autoconf.
|
||||
|
||||
\subsection{AutoConf}
|
||||
|
||||
Le script configure se charge de regarder où sont les bibliothèques standard
|
||||
ainsi que le compilateur et tout et tout.
|
||||
|
||||
On a la flemme d'écrire le script pour autotools ... donc : \texttt{autoscan} !
|
||||
Première chose à faire : renommer le fichier en configure.ac
|
||||
|
||||
Il crée un fichier configure.scan. C'est un script shell mélangé avec du M4 (le
|
||||
\og language d'AutoConf\fg).
|
||||
\c Ca fonctionne sur le même principe que cpp, le préprocesseur.
|
||||
|
||||
M4 = Macro = M + 4 lettre
|
||||
|
||||
Les crochets bloquent l'extension des macros. Conseil : toujours mettre des
|
||||
crochets autour des variables.
|
||||
|
||||
On retrouve des infos pour autoconf et automake.
|
||||
|
||||
AC_PREREQ vérifier la version requise.
|
||||
|
||||
AC_INIT : initialisation du package (nom, version, adresse de bug report)
|
||||
|
||||
AC_PROG_CXX : macro qui cherche un compilateur C++, on peut préciser le
|
||||
compilateur obligatoire à utiliser (on lui passe en argument de
|
||||
\texttt{./configure CXX=g++}) et il vérifie que le compilateur fonctionne (il
|
||||
compile un petit code pour voir :p)
|
||||
|
||||
Si le compilateur fonctionne pas par exemple, il dira ce qui va pas, plus de
|
||||
détails sont dispo dans le fichier config.log (énormément !)
|
||||
|
||||
|
||||
AC_CONFIG_FILES : fichiers à générer, typiquement des Makefiles !
|
||||
Il prend des fichiers en .in et il génére des fichiers dont le nom est écrit
|
||||
dans la variable : Makefile.in => Makefile ; c'est donc le script configure qui
|
||||
transforme le .in en véritable fichier.
|
||||
C'est à ce moment là qu'il précise les variables genre CXX, ...
|
||||
|
||||
AC_OUTPUT déclenche la génération de tout ce qu'on a prévu jusque là.
|
||||
|
||||
|
||||
Pour le moment, il nous manque donc les .in ; c'est automake qui va les générer
|
||||
à partir des .am :)
|
||||
Et puis, on va appeler autoconf pour générer le configure
|
||||
|
||||
Pour dire à autoconf qu'on veut utiliser automake, on va ajouter une macro :
|
||||
AM_INIT_AUTOMAKE()
|
||||
On va ajouter deux arguments : foreign pour dire qu'on veut pas les contraintes
|
||||
d'un projet GNU et 1.11 pour la version minimale d'automake
|
||||
|
||||
|
||||
Bon en fait on va utiliser \texttt{aclocal} :p
|
||||
C'est pour préparer autoconf : pour récupérer les macros que l'on va utiliser
|
||||
dans les fichiers.
|
||||
|
||||
Le but de M4 est de faciliter la maintenance, c'est plein de bouts de script
|
||||
shell qui sont concaténé.
|
||||
|
||||
Allé hop, \texttt{automake} !
|
||||
Hmmm ... il a besoin de certain script
|
||||
\begin{itemize}
|
||||
\item \textbf{depcomp~:} comment le compilateur gère les dépendances
|
||||
(makedepend outdated : il regarde les fichiers dans tous les répertoires et
|
||||
calcul les dépendances pour chaque fichier et il génère un bout de makefile
|
||||
qui est à inclure. Mais c'est chiant, c'est pas automatisé, ...)~;\\
|
||||
La première fois qu'on compile, le compilateur se balade et détecte les
|
||||
dépendances entre les .h et les .c (avec des options louches -MT -MD) il
|
||||
inscrit les dépendances dans un fichier et c'est automatisé ! depcomp teste
|
||||
donc le compilateur pour déterminer les options à utiliser.
|
||||
\end{itemize}
|
||||
|
||||
Pour avoir les scripts manquant on fait : \texttt{automake -ac}
|
||||
|
||||
Youpla, on lance \texttt{autoconf}. Il dit rien, mais il bosse dur !
|
||||
|
||||
C'est tout pour la partie mainteneur du paquet.
|
||||
|
||||
\subsection{Let's play !}
|
||||
|
||||
\texttt{./configure}
|
||||
|
||||
Il vérifie tout un tas de truc useless : faut lire il parle beaucoup trop vite.
|
||||
|
||||
Il prépare le mécanisme de dépendance et à la fin, il crée le Makefile.
|
||||
|
||||
Le Makefile est composé de régles classiques et d'une multitude de variables.
|
||||
|
||||
\texttt{make}
|
||||
|
||||
Bon ba voilà, ça compile donc ça marche !
|
||||
Il y a plein de trucs sur la ligne de compilation : plein de \texttt{-D} qui
|
||||
définissent des constantes (du style~: \texttt{HAVE_STRNCMP} qui dit si strncmp
|
||||
a un comportement correct, quand c'est mélangé avec autoconf, ça s'utilise
|
||||
comme une constante de préprocesseur).
|
||||
Le problème de l'approche c'est qu'elle est limité : on a moins d'une dizaine
|
||||
d'options. Dans un grand projet, le compilo ou le shell peuvent dire que la
|
||||
ligne est trop longue.
|
||||
Pour ça, on peut demander à autoconf de générer un fichier config.h
|
||||
|
||||
|
||||
\section{Mooooaaaaarrree}
|
||||
|
||||
Tips Doxygen \a dit que c'est un attribut ce qui suit.
|
||||
|
||||
\subsection{Ajouter une bibliothèque}
|
||||
|
||||
Nouvelle variable primaire : LIBRARIES, préfixée par le nom du répertoire où se
|
||||
sera installé.
|
||||
|
||||
Idem, on prend le nom de la lib à générer (libgreet.a) qui devient le
|
||||
préfixe. Puis on ajoute les SOURCES...
|
||||
|
||||
Si on fait les choses bien, \texttt{make} devrait tout régénérer si on modifie
|
||||
comme ça !
|
||||
|
||||
Arg, il a pas trouvé RANLIB pour faire des lib. M'enfin, il dit qu'il faut le
|
||||
rajouter...
|
||||
|
||||
Tips \texttt{nm} : on peut utiliser c++filt pour retirer le mangling :
|
||||
\texttt{nm libgreet.a | c++filt}
|
||||
|
||||
\subsection{Utiliser la bibliothèque}
|
||||
|
||||
Cette fois, on a une dépendance. Il ne faudra donc pas oublié de dire qu'on a
|
||||
besoin de la libgreet !
|
||||
On utilise pour ça le suffixe \texttt{LDADD}, on indique ensuite le nom de la
|
||||
lib à utiliser.
|
||||
|
||||
|
||||
\section{Suite de tests}
|
||||
|
||||
\texttt{TESTS} : appel un ou plusieurs programmes
|
||||
|
||||
Dans les machins, si on remplace le préfixe \texttt{bin} par \texttt{check}, le
|
||||
programme ainsi listé ne sera compilé que si on lance un \texttt{make check}.
|
||||
|
||||
\subsection{make distcheck}
|
||||
|
||||
Tarball via dist + detar ailleurs + check
|
||||
|
||||
"Parallel build" : on peut se placer dans un dossier build par exemple et
|
||||
appeler ../configure. Il va alors tout compiler dans ce dossier.
|
||||
(genre, on se place dans le goinfre local pour éviter de compiler sur l'AFS)
|
||||
|
||||
Moment historique, faut verser une petite larme :( Le bocal avait l'air
|
||||
compétent ... Lulz le boulot perdu car sauvé dans le goinfre effacé à 3h42 :p
|
||||
|
||||
Tips pour débugger : \texttt{../configure CXXFLAGS="-O0 -g"} à faire dans un
|
||||
répertoire \texttt{build_debug}, avoir un autre répertoire \texttt{build_fast}
|
||||
avec \texttt{-O3 -DNDEBUG}, \ldots un build par architecture, \ldots
|
||||
|
||||
\paragraph{C'est parti~!}
|
||||
|
||||
Il trouve pas un fichier : hop on l'ajoute dans le Makefile.am :
|
||||
\texttt{EXTRA_DIST}.
|
||||
|
||||
Maintenant, il ne trouve pas un fichier qui a une adresse relative ! Vu que
|
||||
distcheck est dans un répertoire \texttt{build/}.
|
||||
|
||||
Il faut changer le script~: le générer (il sera donc généré dans le builddir).
|
||||
On crée donc \texttt{test-cat.in}~:
|
||||
|
||||
On ajoute la variable \texttt{@srcdir@} à l'endroit où l'on veut que se soit
|
||||
remplacé.
|
||||
Dans le \texttt{configure.ac}, on ajoute un fichier à générer aux côtés du
|
||||
Makefile. Arf, mais il est pas exécutable dans ce cas. Donc, on lui dit que
|
||||
c'est exécutable en ajoute un second argument qui est une commande qui est
|
||||
exécuté après~: \texttt{[chmod +x mon-test]}
|
||||
|
Reference in New Issue
Block a user