Autotools
Posted on mai 17, 2022 in computer-science
Note: Ce document est une mise à jour de mon article comment utiliser les « autotools » pour créer et distribuer des packages .tar.gz
« à la GNU » pubkié en 2001.
Prérequis
Si vous désirez exécuter les commandes décrites dans ce tutorial, il faut un système de compilation. Sous Ubuntu :
sudo apt install build-essential autoconf libtool
Créer des paquetages tar.gz avec les autotools
N’avez vous jamais eu envie de distribuer vos projets sous la forme
d’un paquetage .tar.gz
comme ceux du projet
GNU ?
Le premier avantage est que l’installation est normalisée: en général, une simple commande
./configure && make && make install
suffit pour compiler et installer un paquetage (et make uninstall
pour tout désinstaller).
Le deuxième avantage est que le script configure
détecte les
particularités du système sur lequel s’effectue l’installation. Cela
permet d’écrire des programmes qui s’adaptent et compilent sur des
systèmes très variés. Même si vous ne programmez pas en C et
distribuez de simples scripts, en shell ou awk par exemple, la
création d’un paquetage "à la GNU" permet une installation automatique
et propre: configure
détecte où se trouvent les programmes shell ou
awk (dans /bin
, /usr/bin
ou /usr/local/bin
, ...), et modifie la
première ligne des scripts en conséquence. Il peut également installer
les documentations (pages ‘man’ ou ‘info’) aux endroits appropriés.
Les paquetages GNU obéissent à des règles très précises et assez
complexes. Il existe des outils qui aident à générer de tels
paquetages : les principaux sont autoconf
et automake
. Toutefois,
leur documentation est d’un abord quelque peu difficile. Cet article
montre, sur un exemple simple, comment les utiliser pour créer des
paquetages .tar.gz
.
Notre projet est un simple programme en C, consistant en un unique
fichier source nommé, au hasard, hello.c
. En premier lieu, il faut
créer un répertoire pour le projet (mkdir hello
), puis, à
l’intérieur de ce répertoire, un sous-répertoire src
dans lequel
sera plaçé le fichier hello.c
:
mkdir -p hello/src
cd hello
cat > src/hello.c <<EOF
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
int main()
{
printf("%s %s\n", PACKAGE,VERSION);
printf("Hello world!\n");
printf("Size of int = %d bytes\n", SIZEOF_INT);
#ifdef WORDS_BIGENDIAN
printf("Big endian\n");
#else
printf("Small endian\n");
#endif
}
EOF
Cette version de hello.c
contient quelques lignes de plus que le
programme classique. Ces lignes supplémentaires ont pour but
d’illustrer quelques possibilités d’autoconfiguration. Le fichier
inclus config.h sera généré par l’appel configure, il contiendra,
entre autres, la définition de macros qui spécifient des
caractéristiques de la machine où s’effectue l’installation; par
exemple, WORDS BIGENDIAN
spécifie l’ordre des octets dans les mots, et
SIZEOF_INT
spécifie la taille, en octets, occupé par les variables de
type ‘int’.
Pour générer le projet, il faut maintenant créer quatre fichiers: Makefile.am
, src/Makefile.am
, acconfig.h
et configure.ac
(cf. Table 2).
Makefile.am
indique les sous-répertoires à traiter. src/Makefile.am
indique les binaires à produire et leurs sources. Finalement, le fichier le plus substantiel est configure.ac
.
# Création des fichiers de configuration
# (à executer depuis le repertoire `hello`)
cat > Makefile.am <<EOF
SUBDIRS = src
EOF
cat > src/Makefile.am <<EOF
bin_PROGRAMS = hello
hello_SOURCES = hello.c
EOF
cat > configure.ac <<EOF
AC_INIT([hello], [1.0])
AC_CONFIG_SRCDIR([src/hello.c])
AM_INIT_AUTOMAKE
AC_PROG_CC
AC_CONFIG_HEADER(config.h)
AC_C_BIGENDIAN
AC_CHECK_SIZEOF(int)
AC_OUTPUT(Makefile src/Makefile)
EOF
Une fois ces fichiers créés, il faut générer différents fichiers de
support, en exécutant les commandes suivantes (les caractères #
introduisent des remarques; seules les commandes, situées à leur
gauche, doivent être tapées).
aclocal # crée aclocal.m4
autoheader # crée config.h.in
touch README AUTHORS NEWS ChangeLog
automake -a # crée Makefile.in et src/Makefile.in
autoconf # crée configure
Pour créer un paquetage respectant à la lettre les standards GNU, il
est nécessaire de créer les fichiers NEWS
, README
, AUTHORS
et
ChangeLog
dans le répertoire principal du projet. Les informations
qui doivent apparaître dans ces fichiers sont précisées dans la
documentation info GNU coding standards, mais les gens pressés
pourront se conformer à cette exigence par un simple touch NEWS
README AUTHORS ChangeLog
.
Ne vous inquiétez pas d’éventuels messages d’avertissement. Par contre
si une commande est inconnue, vérifiez que votre système contient bien
les outils de base de développement GNU tels que le compilateur gcc
,
make
, autoconf
, automake
, etc.
Nous pouvons maintenant effectuer une compilation et une installation:
./configure # create Makefiles
make # compile the package
sudo make install # install the package in /usr/local
Il faut noter que, par défaut, les fichiers sont installés dans
/usr/local
, et donc que l’étape make install
nécessite
d’avoir les droits de super-utilisateur. Néanmoins, on peut installer les
programmes à un autre endroit; par exemple, en exécutant:
configure --prefix=$HOME
les fichiers s’installeront alors dans des sous-répertoires bin
,
man
, etc. du répertoire de l’utilisateur. C’est l’un des avantages
importants de ces paquetages .tar.gz
, par rapport aux .rpm
ou
.deb
, que de pouvoir être installés par un utilisateur qui n’a pas
les droits de superutilisateur.
Vous pouvez lire le fichier INSTALL
qui détaille d’autres options
d’installation.
Générer le paquetage
Pour générer le package hello-0.1.tar.gz
, il ne reste
alors plus qu’à taper:
make dist # crée hello-0.1.tar.gz
make distclean # nettoie le répertoire du projet
Essayez ensuite de décompacter le paquetage, de le compiler et de
l’installer. Si vous avez bien suivi la recette, tout devrait
fonctionner “automagiquement”. Quelques remarques méritent d’être
mentionnées. Le fichier le plus complexe est configure.ac
; cependant
il existe une commande, autoscan
, qui accompli une partie du travail
en produisant un fichier configure.scan
pouvant servir de point de
départ pour l’écriture de ce fichier. Le numéro de version (ici 0.1
)
provient de la ligne AC_INIT
dans configure.ac
. Il est
accessible dans le source par la macro VERSION
. Une fois que vous
avez exécuté ./configure
et que le fichier Makefile
existe dans
votre répertoire, il n’est plus nécessaire d’entrer toute la série de
commandes aclocal
, ... à chaque fois que vous aurez modifié un
fichier (par exemple configure.ac
): une simple commande make
suffira.
Installer de la documentation ou des scripts
Pour installer des pages de manuel, il faut ajouter dans Makefile.am
une ligne commençant par man MANS =
et suivie de la liste des
fichiers au format nroff (p.ex. man MANS = hello.1
). Nous
conseillons de mettre tous ces fichiers dans un sous-répertoire man
de la distribution, et d’ajouter ce répertoire dans la liste SUBDIRS
du fichier Makefile.am
principal.
Supposons maintenant que notre distribution contiennent des scripts
écrit dans le language gawk : script1.awk
et script2.awk
. Nous
voudrions que le chemin de gawk soit détecté automatiquement et que
ces scripts soient installés, sous les noms script1 et script2. Pour
cela, il faut modifier configure.ac et src/Makefile.am. Ajoutez une
ligne ((AC PATH PROGS(GAWK, gawk) )) dans configure.ac; cela vérifiera
la disponibilité de gawk sur le système, et fournira son chemin dans
la variable $(GAWK). Le nouveau src/Makefile.am est listé dans la
table 3. Cet exemple peut facilement être adapté à des scripts écrits
dans des languages quelconques, tcl, perl ou python, par exemple.
### Fichier src/Makefile.am installant des scripts gawk
bin_SCRIPTS = script1 script2
CLEANFILES = $(bin_SCRIPTS)
EXTRA_DIST = script1.awk script2.awk
script1 : script1.awk
echo "#! " $(GAWK) > $@
cat $< >> $@
chmod ugo+x $@
script2 : script2.awk
echo "#! " $(GAWK) > $@
cat $< >> $@
chmod ugo+x $@
Installer une librairie
TODO
Voir * https://www.gnu.org/software/libtool/manual/html_node/Using-Automake.html#Using-Automake * https://www.gnu.org/software/automake/manual/html_node/Libtool-Concept.html
Voici Makefile.am
de ma librarie (http://github/chrlr/expe_c/psychexp) consistant en deux fichiers sources: psychexp.h psychexp.c
lib_LTLIBRARIES=libpsychexp.la
libpsychexp_la_SOURCES=psychexp.h psychexp.c
libpsychexp_la_LIBADD=-lSDL2
include_HEADERS=psychexp.h
expliquer l'utilisation de libtoolize
Créer un paquetage .deb contenant le binaire
Reprenons l'exemple du projet hello
. Les commandes
./configure
make dist
produisent le fichier hello-1.0.tar.gz
.
Nous allons utiliser la commande alien
pour convertir ce “tarball” en en package .deb
pouvant être installé par dpkg
sudo apt install alien
alien -k hello-1.0.tar.gz`
Notez que cet outil ne permet que la création de paquetage binaire, et pas de paquetage source.
(Voir https://help.ubuntu.com/community/CheckInstall pour plus d'information)
Créer un paquetage rpm
(WARNING: cette partie date de 2001 et est très certainement obsolete. Je n'utilse plus de système basé sur rpm depuis 2005).
Certains utilisateurs préférent les paquetages rpm
aux tar.gz
. Il y en
fait deux types de rpm, ceux qui contiennent les sources (src.rpm) et
ceux qui ne contiennent que les exécutables. Les seconds sont
effectivement faciles à installer puisqu’ils ne nécessitent pas de
compilation; mais ils font des hypothèses sur la machine sur laquelle
ils s’installent, et sont donc généralement spécifiques à une
distribution. Créer des paquetages src.rpm
et rpm
à partir de
hello-0.1.tar.gz
n’est pas difficile. La procédure générique est
détaillée dans des documents disponibles sur les sites http://www.rpm.org et
-
copier
hello-4.1.tar.gz
dans/usr/src/packages/SOURCES
(ou/usr/src/redhat/SOURCES
selon votre distribution) -
dans
/usr/src/packages/SPECS
, créer le fichierhello.spec
. Ce fichier décrit le contenu du futur paquetage rpm.
#
# exemple de fichier ‘spec’ pour le projet ‘hello’
#
Vendor: Christophe Pallier
Name: hello
Release: 1
Copyright: GPL (cf http://www.fsf.org)
Group: unsorted
Provides: hello
Packager: christophe@pallier.org
Version: 0.1
Summary: The hello program
Source: hello-0.1.tar.gz
%description
A slightly adapted version of the ‘hello’ program.
%prep
%setup
%build
./configure
make
%install
make install
%files
/usr/local/bin/hello
-
faire
rpm -ba hello.spec
(en tant que root) La commanderpm -ba
crée le fichierhello-0.1-1.rpm
dansRPMS/i386
ethello0.1-1.src.rpm
dansSRPMS
. Si vous distribuez l’exécutable, un superutilisateur pourra effectuer les opérations suivantes:rpm -qip hello-0.1-1.rpm # liste le contenu du paquetage rpm -i hello-0.1-1.rpm # install rpm -qil hello # verifie le paquetage rpm -e ello # desinstalle
Conclusion
Vous voici maintenant parti du bon pied pour créer vos
paquetages. Pour faire des choses plus complexes, vous devrez lire les
documentations au format info: GNU coding standards, Autoconf,
Automake. Le lecture des fichiers configure.ac
des paquetages
existants est également instructive.