autotools

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
autotools [2021/05/12 13:17] – créée phswautotools [2023/04/11 11:06] (Version actuelle) – Add --with-foo phsw
Ligne 6: Ligne 6:
  
  
-Générer automatiquement un `configure.scan`:+ 
 +==== Mise en place minimale ==== 
 + 
 +Générer automatiquement un ''configure.ac'':
 <code bash> <code bash>
 autoscan autoscan
-mv configure.{scan, ac}+mv configure.{scan,ac}
 </code> </code>
 +
 +Créer un ''autogen.sh'':
 +<code bash>
 +#!/bin/bash
 +
 +autoreconf -i
 +</code>
 +
 +''configure.ac'' minimal:
 +<code autoconf>
 +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
 +</code>
 +
 +Un ''Makefile.am'' à la racine du projet (nécessaire pour pouvoir faire `make` directement le dossier où ''configure'' sera exécuté:
 +<code make>
 +SUBDIRS = src
 +</code>
 +
 +''src/Makefile.am'':
 +<code make>
 +bin_PROGRAMS = stream basic_prime
 +
 +stream_SOURCES = stream.c
 +stream_CFLAGS = $(OPENMP_CFLAGS) $(LARGE_MCMODEL_LARGE)
 +
 +basic_prime_SOURCES = basic_prime.c prime.c
 +</code>
 +
 +
 +
 +
 +==== 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
 +<code autoconf>
 +m4_include([m4/m4_ax_gcc_x86_cpu_supports.m4])
 +</code>
 +en haut du configure (sinon ''./config.status --recheck'' peut planter).
 +
 +Une autre solution semble être:
 +<code autoconf>
 +AC_CONFIG_MACRO_DIR([m4])
 +</code>
 +dans le configure ([[https://autotools.io/autoconf/macros.html|source]]).
 +
 +
 +
 +
 +==== Utiliser pkg-config ====
 +
 +Fonctionnement minimal:
 +<code autoconf>
 +PKG_CHECK_MODULES([HWLOC], [hwloc], [have_hwloc=yes], [have_hwloc=no])
 +</code>
 +Paramètres:
 +  - suffixe des variables récupérées depuis pkg-config
 +  - module à chercher avec pkg-config
 +  - optionnel: action à exécuter si le module est trouvé
 +  - optionnel: action à exécuter si le module n'est pas trouvé
 +<code make>
 +program_CFLAGS = $(HWLOC_CFLAGS)
 +program_LDADD = $(HWLOC_LIBS)
 +</code>
 +
 +Sur certains (anciens ?) systèmes, il est nécessaire d'ajouter le script de macros [[https://github.com/pkgconf/pkgconf/blob/2fdc5f0081dcf22fa476767877d13097eb81e255/pkg.m4|pkg.m4]] et d'appeler ''PKG_PROG_PKG_CONFIG'' avant le moindre appel à pkg-config.
 +
 +
 +==== Variable conditionnelle ====
 +
 +<code autoconf>
 +AM_CONDITIONAL(HAVE_HWLOC, test x$have_hwloc = xyes)
 +</code>
 +Cette instruction n'a d'effet que dans les makefiles et doit être toujours exécutée (pas placée dans une condition).
 +<code make>
 +if HAVE_HWLOC
 +bin_PROGRAMS += program_with_hwloc
 +endif
 +</code>
 +
 +
 +==== Chercher un programme ====
 +
 +<code autoconf>
 +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
 +</code>
 +Paramètres:
 +  - Variable qui contiendra le chemin du programme
 +  - Programme à chercher
 +  - 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é.
 +  - 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:
 +<code bash>
 +./configure CFLAGS="-foo"
 +</code>
 +Il faut donc aussi le récupérer dans le configure:
 +<code autoconf>
 +CFLAGS="$CFLAGS -O0 -g"
 +</code>
 +==== Chercher une bibliothèque ====
 +
 +<code autoconf>
 +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)
 +</code>
 +Paramètres de ''AC_CHECK_LIB'':
 +  - nom de la bibliothèque à chercher
 +  - une fonction contenue dans la bibliothèque
 +  - 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'':
 +<code make>
 +if HAVE_LIKWID
 +bin_PROGRAMS += uncore_set
 +
 +uncore_set_SOURCES = uncore_set.c
 +uncore_set_LDADD = $(LIKWID_LIBS)
 +endif
 +</code>
 +
 +Il est possible de définir les flags pour toutes les cibles, en mettant en haut d'un ''Makefile.am'' :
 +<code make>
 +LDADD = $(HWLOC_LIBS)
 +AM_CFLAGS = $(HWLOC_CFLAGS)
 +</code>
 +
 +Il est possible de chercher une bibliothèque et utiliser les flags requis, depuis le fichier ''configure.ac'' ([[https://autotools.info/autoconf/finding.html|source]]) :
 +<code autoconf>
 +AC_SEARCH_LIBS([hwloc_free],[hwloc],,AC_MSG_ERROR([hwloc library unavailable]))
 +</code>
 +
 +
 +
 +==== 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:
 +<code autoconf>
 +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
 +</code>
 +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:
 +<code autoconf>
 +AC_CHECK_DECLS([_mm_stream_si32], [], [], [[#include <x86intrin.h>]])
 +</code>
 +Cela va définir une constante de préprocesseur ''HAVE_DECL__MM_STREAM_SI32''.
 +
 +
 +
 +==== Définir une variable de préprocesseur ====
 +
 +<code autoconf>
 +AC_DEFINE(HAVE_MKL, [1], [Whether MKL is available])
 +</code>
 +Paramètres:
 +  - nom de la define
 +  - valeur
 +  - 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 ====
 +
 +  * [[https://www.gnu.org/software/autoconf/manual/autoconf-2.65/html_node/Canonicalizing.html]]
 +
 +<code autoconf>
 +AC_CANONICAL_HOST
 +if test $host_cpu = x86_64; then
 +    # ...
 +fi
 +</code>
 +
 +
 +
 +
 +==== Tester le support d'un jeu d'instructions ====
 +
 +Utiliser la macro ''AX_GCC_X86_CPU_SUPPORTS'' de l'[[https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpu_supports.html|autoconf-archive]]:
 +<code autoconf>
 +AX_GCC_X86_CPU_SUPPORTS(avx512f, [have_avx512=yes])
 +</code>
 +
 +
 +==== Tester OpenMP ====
 +
 +<code autoconf>
 +AC_OPENMP
 +</code>
 +Les cflags sont ensuite disponibles via ''$(OPENMP_CFLAGS)''.
 +
 +
 +
 +==== Afficher un message ====
 +
 +Pendant le configure:
 +<code autoconf>
 +AC_MSG_NOTICE([
 +
 +Configuration summary:
 +    foo
 +])
 +</code>
 +
 +
 +
 +==== Enable option ====
 +
 +  * [[https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Package-Options.html]]
 +
 +<code autoconf>
 +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
 +</code>
 +
 +On peut ensuite appeler:
 +<code bash>
 +../configure --enable-debug
 +</code>
 +
 +
 +
 +==== Composants externes ====
 +
 +<code autoconf>
 +mpicc_name=mpicc
 +AC_ARG_WITH(mpicc, [AS_HELP_STRING([--with-mpicc=<mpicc name>], [Name of the MPI compiler])],[mpicc_name=$withval])
 +</code>
 +
 +
 +
 +==== .gitignore ====
 +
 +<code>
 +*~
 +Makefile.in
 +/aclocal.m4
 +/autom4te.cache
 +/build
 +/build-aux
 +/configure
 +src/config.h.in
 +</code>
 +
 +
 +
 +
 +
  
  
  • autotools.1620818240.txt.gz
  • Dernière modification : 2021/05/12 13:17
  • de phsw