Everyone is welcome here (except, of course, those who have borrowed books from me for and have not returned them yet 😉)

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 . Essentiellement, il s’agit de crĂ©er un fichier texte, ayant pour extension .spec, qui dĂ©crit le paquetage. Pour ‘hello’, voici la marche Ă  suivre:

  1. copier hello-4.1.tar.gz dans /usr/src/packages/SOURCES (ou /usr/src/redhat/SOURCES selon votre distribution)

  2. dans /usr/src/packages/SPECS, créer le fichier hello.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
  1. faire rpm -ba hello.spec (en tant que root) La commande rpm -ba crĂ©e le fichier hello-0.1-1.rpm dans RPMS/i386 et hello0.1-1.src.rpm dans SRPMS. 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.