\firstslide{GNU Autotools}

Que sont-ce~?

\begin{itemize}
\item \textbf{Autoconf} simplifie la configuration
\item \textbf{Automake} simplifie l'écriture des \texttt{Makefile}'s
\item \textbf{Libtool} simplifie la création de bibliothèques dynamiques
\end{itemize}

\adviwait

{\small
$\Rightarrow$ Équipement complet d'un projet (tests, installation,
cross-compilation...) \\ 
\adviwait
$\Rightarrow$ Portabilité \\
\adviwait
$\Rightarrow$ Respect des standards de projets GNU ou assimilés
}

%%%%%%%%%%%%%%%%%%%%%%%% PLAN %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newslide{Plan}

\begin{itemize}
\item Background~: problèmes à surmonter et historique
\item Principe de fonctionnement
\item Applications
\end{itemize}

\newslide{Background}

\begin{multicols}{2}
Configuration~:
{\small
\begin{itemize}
\item Mais où est le compilateur~?
\item Quelles fonctions sont disponibles~?
\item Quelles sont les caractéristiques du CPU~?
\end{itemize}
}

\adviwait
\columnbreak
Make~:
{\small
\begin{itemize}
\item Où sont les bibliothèques~?
\item Où installer~?
\item Comment connaître les dépendances~?
\end{itemize}
}
\end{multicols}

{\small
\adviwait
Autres~: chemins d'installation, génération automatique de documentation,
batteries de tests...
}

%%%%%%%%%%%%%%%%%%%%%%%%% PORTABILITÉ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\newslide{Portabilité 1/4}

Assurer la compilation et le bon fonctionnement sur tous les systèmes

{\small
\begin{multicols}{2}
\begin{itemize}
\item conformité avec les conventions d'appel (\texttt{RETSIGTYPE}, membres
de \texttt{struct stat}...)
\item vérification des fonctions et types disponibles (\texttt{strdup},
\texttt{alloca}, \texttt{roundf}, \texttt{long long}...)
\end{itemize}

\columnbreak
\begin{itemize}
\item retrouver les \textit{headers} et bibliothèques où sont définies les
fonctions (nécessité ou non de \texttt{-I}, \texttt{-L}, \texttt{-lm}, \texttt{-ldl} ...)

\item bonne utilisation d'extensions spécifiques \\
(\texttt{C99},
\verb+__attribute__((unused))+...)
\end{itemize}

\end{multicols}
}

\newslide{Portabilité 2/4}

Changer de comportement selon les systèmes

{\small
\begin{multicols}{2}
\begin{itemize}
\item optimisation par compilation conditionnelle (ex: \texttt{sizeof}, assembleur inline...)
\item utiliser le jeu d'appels systèmes local (ex: \texttt{exec}/\texttt{spawn})
\end{itemize}

\columnbreak
\begin{itemize}
\item adapter le traitement des chemins (ex: \verb+C:\+, \texttt{/},
\texttt{:}, \texttt{.exe})
\item adapter l'interface aux périphériques (ex: son avec OSS, DirectSound,
USS...)
\end{itemize}
\end{multicols}
}

\newslide{Portabilité 3/4}

Solutions possibles~:

{\small
\begin{itemize}
\item Répertorier toutes les combinaisons architecture/OS, entretenir des jeux de
\texttt{Makefile} / \texttt{\#define} pour chacun

$\Rightarrow$ difficile à
maintenir
\adviwait
\item \textbf{Autoconf~:} tester chaque fonctionnalité requise au moment de
la compilation, générer \texttt{Makefile} / \texttt{\#define} en fonction du
résultat.
\end{itemize}
}

\newslide{Portabilité 4/4}

\begin{multicols}{2}
Pauvreté du \texttt{make} standard~:
{\small
\begin{itemize}
\item pas de syntaxe de réécriture de macros universelle
\item pas de gestion automatique des dépendances
\item peu de règles prédéfinies
\end{itemize}
$\Rightarrow$ \texttt{Makefile} verbeux, beaucoup d'information redondante
}

\adviwait
\columnbreak
Solutions~:
{\small
\begin{itemize}
\item imposer l'utilisation d'une version de \texttt{make} riche (GNU Make, dmake...)

$\Rightarrow$ contraignant pour l'utilisateur
\adviwait
\item \textbf{Automake~:} automatiser l'écriture de \texttt{Makefile}'s standards
\end{itemize}
}
\end{multicols}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% HISTORIQUE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newslide{Historique}

David J. MacKenzie (Autoconf/Automake), Akim Demaille (Autoconf), Gordon
Matzigkeit (Libtool)
{\small
\begin{description}
\item[Préhistoire] un script shell \texttt{configure} transforme
\texttt{Makefile.in} en \texttt{Makefile}
\item[Autoconf 1] (1992) \texttt{autoconf} transforme \texttt{configure.in} en
\texttt{configure}
\item[Autoconf 2] (1994) cross-compilation, sous-répertoires, cache des
résultat, plus de tests...
\item[Automake] (1994) \texttt{automake} transforme \texttt{Makefile.am} en
\texttt{Makefile}
\item[Libtool] (1996) change le comportement d'Automake
\end{description}
}

\newslide{Anachronismes}

\emph{Attention} aux changements entre Autoconf 2.13 et 2.50, Automake 1.4 et 1.5, Libtool 1.4.2 et 1.5
{\small
\begin{itemize}
\item Autoconf 2.13 a duré très longtemps $\Rightarrow$ Automake 1.4 répare et
complète Autoconf 2.13
\item Libtool 1.4.2 adapté à Automake 1.4 et Autoconf 2.13
\item Automake 1.5 change l'architecture d'Automake
\item Autoconf $>=$ 2.50 incompatible avec Automake 1.4 et Libtool 1.4.2
\end{itemize}
}

%%%%%%%%%%%%%%%%%%%%%%%%%% PRINCIPE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newslide{Principe Général}

\center{\includegraphics[width=.7\textwidth]{general}}

\newslide{Autoconf 1/4}

{\small
\begin{multicols}{2}
\textbf{configure.ac}
\begin{itemize}
\item préprocessé par GNU m4
\item macros de contrôle~: \\
\verb+AC_INIT+, \verb+AC_PREREQ+...
\item macro tests~: \verb+AC_PROG_CC+...
\item macros d'actions résultantes~: \\
\verb+AC_SUBST+, \verb+AC_DEFINE+...
\end{itemize}

\columnbreak
\textbf{configure} (shell script)
\begin{itemize}
\item dépend d'un shell «~standard~»
\item teste et génère \textbf{config.status}
\item \textbf{config.status} effectue les actions résultantes
\end{itemize}
\end{multicols}
}

\newslide{Autoconf 2/4}

{\small
\begin{multicols}{2}
\textbf{config.h.in}
\begin{itemize}
\item contient des lignes 
\begin{verbatim}
#undef HAVE_XXX
\end{verbatim}
\item transformé en \textbf{config.h} par \texttt{config.status}
avec \texttt{\#undef}$\rightarrow$\texttt{\#define}
\item contrôle par \verb+AC_DEFINE+
\item générable automatiquement par \texttt{autoheader}
\end{itemize}

\adviwait
\columnbreak
\textbf{Makefile.in} et autres substitués
\begin{itemize}
\item contient des occurences de \texttt{@VAR@}
\item occurences de \texttt{@VAR@} substituées par
\texttt{config.status}
\item contrôle par \verb+AC_SUBST+
\end{itemize}
\end{multicols}
}

\newslide{Autoconf 3/4}

{\small
\begin{multicols}{2}
\textbf{config.h.in}
\adviembed[width=.4\textwidth,height=.3\textwidth]{./xterm.sh !g vim config-h/configure.ac}

\columnbreak
\textbf{Makefile.in} et autres substitués
\adviembed[width=.4\textwidth,height=.3\textwidth]{./xterm.sh !g vim Makefile-in/configure.ac}

\end{multicols}
}

\newslide{Autoconf 4/4}

{\small
\begin{multicols}{2}
\textbf{config.h.in}
\adviembed[width=.4\textwidth,height=.17\textwidth]{./xterm.sh !g vim config-h/config.h.in}
\adviembed[width=.4\textwidth,height=.17\textwidth]{./xterm-cd.sh !g config-h ./configure && zsh}

\adviwait
\columnbreak
\textbf{Makefile.in} et autres substitués
\adviembed[width=.4\textwidth,height=.17\textwidth]{./xterm.sh !g vim Makefile-in/Makefile.in}
\adviembed[width=.4\textwidth,height=.17\textwidth]{./xterm-cd.sh !g Makefile-in ./configure && zsh}

\end{multicols}
}

\newslide{Automake 1/3}

{\small
\begin{itemize}
\item \textbf{Makefile.am} préprocessé par Automake (Perl)
\item syntaxe Make \emph{étendue}
\item génère des «~patrons~» pour l'entrée de \textbf{config.status}
\item génère des règles de regénération récursive 
\end{itemize}
}

\newslide{Automake 2/3}

\begin{multicols}{2}
Règles de construction~:
\begin{verbatim}
bin_PROGRAMS = 42sh
42sh_SOURCES = main.c 
42sh_LDADD = -L. -lshell
42sh_DEPENDENCIES = libshell.a

noinst_LIBRARIES = libshell.a
libshell_a_SOURCES = shell.c glob.c
\end{verbatim}

\columnbreak
Règles de contrôle~:
\begin{verbatim}
CLEANFILES = \*~ \#*
\end{verbatim}

Changement du préfixe~: \\
\verb+bin_+, \verb+dist_+, \verb+nobase_+
\end{multicols}

\newslide{Automake 3/3}

Dans le \textbf{Makefile} généré~:

{\small
\begin{multicols}{2}
\begin{itemize}
\item \texttt{all}
\item \texttt{dist}
\item \texttt{check}, \texttt{distcheck}
\item \texttt{doc}
\item \texttt{install, uninstall}
\end{itemize}

\columnbreak
\begin{itemize}
\item \texttt{clean}
\item \texttt{distclean}
\item \texttt{maintainer-clean}
\item \texttt{Makefile}, \texttt{Makefile.in}, \texttt{configure}...
\end{itemize}
\end{multicols}
}

\newslide{Macros disponibles}

Dans les pages info de Autoconf et Automake~:

\begin{multicols}{2}
\adviembed[width=.4\textwidth,height=.3\textwidth]{./xterm.sh !g pinfo autoconf}

\columnbreak
\adviembed[width=.4\textwidth,height=.3\textwidth]{./xterm.sh !g pinfo automake}
\end{multicols}

\newslide{Fichiers annexes}

\texttt{install-sh}, \texttt{missing}, \texttt{texinfo.tex},
\texttt{mkinstalldirs}, \texttt{depcomp}...

$\Rightarrow$ utilisés par Automake pour certaines règles

\adviwait
$\Rightarrow$ auto-importés par \texttt{autoreconf -i}

\newslide{Applications}

(démonstration à côté)

{\small
\begin{itemize}
\item utilisation de Lex et Yacc
\item utilisation de Texinfo
\item utilisation sommaire de \texttt{make check} 
\end{itemize}
}

\newslide{Ouvertures}

{\small
\begin{itemize}
\item Autotest
\item Libtool
\end{itemize}
}

