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