Table des matières

Autotools

Mise en place minimale

Générer automatiquement un configure.ac:

autoscan
mv configure.{scan,ac}

Créer un autogen.sh:

#!/bin/bash
 
autoreconf -i

configure.ac minimal:

AC_PREREQ([2.69])
AC_INIT([nom-du-projet], [version], [em@il])
AC_CONFIG_AUX_DIR([build-aux]) # place les scripts auxiliaires dans ce dossier
AM_INIT_AUTOMAKE([foreign -Wall -Werror]) # foreign: relâche la pression sur les standards GNU, -Wall et -Werror concernent automake
AC_CONFIG_SRCDIR([src/bench.c]) # emplacement d'un fichier source, permet à configure de s'assurer que les fichiers sources sont bien là où c'est indiqué
AC_CONFIG_HEADERS([src/config.h]) # dans quel fichier iront les AC_DEFINE
 
AM_SILENT_RULES(yes) # n'affiche pas le détail des commandes exécutées
 
AC_PROG_CC # cherche un compilateur C
AM_PROG_CC_C_O # enable per-target flags, required for automake < 1.14
 
AC_CONFIG_FILES([Makefile src/Makefile]) # liste des fichiers Makefile à traiter
AC_OUTPUT

Un Makefile.am à la racine du projet (nécessaire pour pouvoir faire `make` directement le dossier où configure sera exécuté:

SUBDIRS = src

src/Makefile.am:

bin_PROGRAMS = stream basic_prime
 
stream_SOURCES = stream.c
stream_CFLAGS = $(OPENMP_CFLAGS) $(LARGE_MCMODEL_LARGE)
 
basic_prime_SOURCES = basic_prime.c prime.c

Utiliser des macros de l'autotools-archive

https://www.gnu.org/software/autoconf-archive/The-Macros.html

Placer le fichier source de la macro dans un dossier m4 à la racine du projet, et ajouter le paramètre -I m4 à la commande autoreconf.

A priori il faut aussi placer

m4_include([m4/m4_ax_gcc_x86_cpu_supports.m4])

en haut du configure (sinon ./config.status –recheck peut planter).

Une autre solution semble être:

AC_CONFIG_MACRO_DIR([m4])

dans le configure (source).

Utiliser pkg-config

Fonctionnement minimal:

PKG_CHECK_MODULES([HWLOC], [hwloc], [have_hwloc=yes], [have_hwloc=no])

Paramètres:

  1. suffixe des variables récupérées depuis pkg-config
  2. module à chercher avec pkg-config
  3. optionnel: action à exécuter si le module est trouvé
  4. optionnel: action à exécuter si le module n'est pas trouvé
program_CFLAGS = $(HWLOC_CFLAGS)
program_LDADD = $(HWLOC_LIBS)

Sur certains (anciens ?) systèmes, il est nécessaire d'ajouter le script de macros pkg.m4 et d'appeler PKG_PROG_PKG_CONFIG avant le moindre appel à pkg-config.

Variable conditionnelle

AM_CONDITIONAL(HAVE_HWLOC, test x$have_hwloc = xyes)

Cette instruction n'a d'effet que dans les makefiles et doit être toujours exécutée (pas placée dans une condition).

if HAVE_HWLOC
bin_PROGRAMS += program_with_hwloc
endif

Chercher un programme

have_mpi=no
AC_PATH_PROG(mpicc_path, mpicc, [no])
AM_CONDITIONAL([HAVE_MPI], [test x$mpicc_path != xno])
if test x$mpicc_path != xno; then
    CC=$mpicc_path
    have_mpi=yes
fi

Paramètres:

  1. Variable qui contiendra le chemin du programme
  2. Programme à chercher
  3. Optionnel: valeur par défaut si le programme n'est pas trouvé. Par défaut, renvoie une chaîne de caractères vide si le programme n'est pas trouvé.
  4. Il est aussi possible de préciser le PATH

Compilateur

Changer le compilateur

Il suffit de définir la variable CC avant de faire appel à AC_PROG_CC

CFLAGS

Des CFLAGS sont positionnés par défaut dès que l'on fait un test qui implique un compilateur. Il faut donc définir les CFLAGS au début du configure.

L'utilisateur peut ajouter des CFLAGS en lançant:

./configure CFLAGS="-foo"

Il faut donc aussi le récupérer dans le configure:

CFLAGS="$CFLAGS -O0 -g"

Chercher une bibliothèque

have_likwid=no
AC_CHECK_LIB([likwid], [topology_init],
             [LIKWID_LIBS=-llikwid
              have_likwid=yes])
AC_SUBST([LIKWID_LIBS])
AM_CONDITIONAL(HAVE_LIKWID, test x$have_likwid = xyes)

Paramètres de AC_CHECK_LIB:

  1. nom de la bibliothèque à chercher
  2. une fonction contenue dans la bibliothèque
  3. optionnel: action à faire si la bibliothèque est trouvée. Sans action ici, tous les binaires seront compilés en étant liés à cette bibliothèque

AC_SUBST permet de remplacer dans tous les makefiles la variable LIKWID_LIBS:

if HAVE_LIKWID
bin_PROGRAMS += uncore_set
 
uncore_set_SOURCES = uncore_set.c
uncore_set_LDADD = $(LIKWID_LIBS)
endif

Il est possible de définir les flags pour toutes les cibles, en mettant en haut d'un Makefile.am :

LDADD = $(HWLOC_LIBS)
AM_CFLAGS = $(HWLOC_CFLAGS)

Il est possible de chercher une bibliothèque et utiliser les flags requis, depuis le fichier configure.ac (source) :

AC_SEARCH_LIBS([hwloc_free],[hwloc],,AC_MSG_ERROR([hwloc library unavailable]))

Chercher une fonction dans une bibliothèque

Il est nécessaire de mettre à jour les flags pour que le compilateur puisse linker la bibliothèque où la fonction est supposée être:

PKG_CHECK_MODULES([STARPU], [starpumpi-1.3], [have_starpu=yes], [have_starpu=no])
AM_CONDITIONAL(HAVE_STARPU, test x$have_starpu = xyes)
if test x$have_starpu = xyes; then
    save_LIBS="$LIBS"
    save_CFLAGS="$CFLAGS"
    CFLAGS="$CFLAGS $STARPU_CFLAGS"
    LIBS="$LIBS $STARPU_LIBS"
    AC_CHECK_FUNCS([starpu_free_noflag])
    CFLAGS="$save_CFLAGS"
    LIBS="$save_LIBS"
fi

Cela va définir une constante de préprocesseur HAVE_STARPU_FREE_NOFLAG si la fonction est trouvée.

Il est possible de chercher des fonctions en précisant dans quel fichier d'en-tête chercher:

AC_CHECK_DECLS([_mm_stream_si32], [], [], [[#include <x86intrin.h>]])

Cela va définir une constante de préprocesseur HAVE_DECL__MM_STREAM_SI32.

Définir une variable de préprocesseur

AC_DEFINE(HAVE_MKL, [1], [Whether MKL is available])

Paramètres:

  1. nom de la define
  2. valeur
  3. description, qui servira de commentaire dans le fichier où sera généré la define (définie par AC_CONFIG_HEADERS)

Connaître l'architecture processeur

AC_CANONICAL_HOST
if test $host_cpu = x86_64; then
    # ...
fi

Tester le support d'un jeu d'instructions

Utiliser la macro AX_GCC_X86_CPU_SUPPORTS de l'autoconf-archive:

AX_GCC_X86_CPU_SUPPORTS(avx512f, [have_avx512=yes])

Tester OpenMP

AC_OPENMP

Les cflags sont ensuite disponibles via $(OPENMP_CFLAGS).

Afficher un message

Pendant le configure:

AC_MSG_NOTICE([
 
Configuration summary:
    foo
])

Enable option

AC_MSG_CHECKING(whether debug mode should be enabled)
AC_ARG_ENABLE(debug, [AS_HELP_STRING([--enable-debug], [enable debug mode])],
                        enable_debug=$enableval, enable_debug=no)
AC_MSG_RESULT($enable_debug)
 
if test x$enable_debug = xyes; then
    CFLAGS="$CFLAGS -O0 -g"
else
    CFLAGS="$CFLAGS -O3"
fi

On peut ensuite appeler:

../configure --enable-debug

Composants externes

mpicc_name=mpicc
AC_ARG_WITH(mpicc, [AS_HELP_STRING([--with-mpicc=<mpicc name>], [Name of the MPI compiler])],[mpicc_name=$withval])

.gitignore

*~
Makefile.in
/aclocal.m4
/autom4te.cache
/build
/build-aux
/configure
src/config.h.in