Noeud:Anatomy of GNU M4s configure.ac, Noeud « Next »:, Noeud « Previous »:Simple Uses of Autoconf, Noeud « Up »:Autoconf



Anatomy of GNU M4´s configure.ac

The Autoconf world, or better yet, the GNU Build System world is immense. Reading the documentation of these tools (Autoconf, Automake, Libtool) and exercising them on a genuine package is the only means to get used to them. Nevertheless, understanding an configure.ac is a first required step. This section is devoted to an explanation of a very representative configure.ac: M4's.

As for any non trivially short file, the very first section of M4's configure.ac contains its copyright and license, in comments.

     # Configure template for GNU m4.			-*-Autoconf-*-
     # Copyright 1991-1994, 2000, 2001  Free Software Foundation, Inc.
     #
     # This program is free software; you can redistribute it and/or modify
     ...
     
     Example : GNU M4's configure.ac -- (i) License
     


Then, it requires at least Autoconf 2.53, because it relies on Autoconf and Autotest features available only since then. While this macro was first meant to have a nice error message if your Autoconf was too old, this clause takes an increasing importance these days. Indeed, on systems such as Debian GNU/Linux which ship several concurrent versions of Autoconf, it is used to decide which should be run.

Extreme caution is taken in Autoconf to catch macros which are not expanded. Typically, finding m4_define in the output is highly suspicious. As a matter of fact, any token starting with m4_ or AC_ is suspected of being an M4 or Autoconf macro that was not expanded, or simply nonexistent. In the present case, since we use variables which names start with m4_cv_, we inform the system they are valid. Similarly, to make sure no macro named jm_* (e.g., jm_PREREQ_ERROR) is left unexpanded, we forbid this pattern, and immediately make an exception for variables named jm_cv_*.

     ## -------------------------- ##
     ## We need a modern Autotest. ##
     ## -------------------------- ##
     AC_PREREQ([2.53])
     m4_pattern_allow([^m4_cv_])
     # We use some of Jim's macros.
     m4_pattern_forbid([^jm_])
     m4_pattern_allow([^jm_cv_])
     
     Example : GNU M4's configure.ac -- (ii) Requirements
     


Then, Autoconf is initialized and the package identified. The invocation to AC_CONFIG_SRCDIR stands for "when running configure, make sure that we can properly find the source hierarchy by checking for the presence of src/m4.h".

The GNU Build System relies on a myriad of little tools to factor workarounds portability issue. For instance, mkinstalldirs is nothing but a portable mkdir -p, building a directory and possibly its parents. Such auxiliary quickly populate the top level of a package: AC_CONFIG_AUX_DIR(config) requires to store them in the directory config. The name of this directory is available in configure as $ac_aux_dir.

GNU M4 uses Automake to handle the Makefiles, see Automake. Automake too has to face portability issues: invoking AM_INIT_AUTOMAKE lets it perform the checks it needs. As using configuration headers implies some additional work in the Makefiles, Automake needs that you use AM_CONFIG_HEADERS instead of AC_CONFIG_HEADERS, but it is really the same.

Voir Using Autotest with the GNU Build System, for an explanation of the last two invocations, related to the test suite.

     ## --------------------------------- ##
     ## GNU Build System initialization.  ##
     ## --------------------------------- ##
     # Autoconf.
     AC_INIT([GNU m4], [1.4q], [bug-m4@gnu.org])
     AC_CONFIG_SRCDIR([src/m4.h])
     AC_CONFIG_AUX_DIR(config)
     
     # Automake.
     AM_INIT_AUTOMAKE
     AM_CONFIG_HEADER(config.h:config-h.in)
     
     # Autotest.
     AC_CONFIG_TESTDIR(tests)
     AC_CONFIG_FILES([tests/m4], [chmod +x tests/m4])
     
     Example : GNU M4's configure.ac -- (iii) Initialization of the
     GNU Build System
     
GNU Build System


Because people scattered through out the planet who collaboratively on GNU M4, it is under the control of CVS, see Source Code Management. Since anyone can fetch a snapshot of M4 at any moment, the concept of version number is insufficient. The following section makes sure that non released versions or betas of GNU M4 (which, by convention, end with an "odd letter") have an additional version information: the references of the latest update of ChangeLog.

     ## ---------------------------------------- ##
     ## Display a configure time version banner. ##
     ## ---------------------------------------- ##
     TIMESTAMP=
     case AC_PACKAGE_VERSION in
       *[[acegikmoqsuwy]])
         TIMESTAMP=`$CONFIG_SHELL $ac_aux_dir/mkstamp < $srcdir/ChangeLog`
         AS_BOX([Configuring AC_PACKAGE_TARNAME AC_PACKAGE_VERSION$TIMESTAMP])
         echo
         ;;
     esac
     AC_DEFINE_UNQUOTED([TIMESTAMP], ["$TIMESTAMP"],
         [Defined to a CVS timestamp for alpha releases of M4])
     
     Example : GNU M4's configure.ac -- (iv) Fine version information
     

Note that this timestamp is provided to the C code via...

AC_DEFINE (variable, [value = 1], [description]) Macro
AC_DEFINE_UNQUOTED (variable, [value = 1], [description]) Macro

Output #define variable value in the configuration headers. In the second form, regular shell expansion (back quotes, variables etc.) is performed on value.

As a result, m4 can provide detailed version information:

     $ m4 --version | sed 1q
     GNU m4 1.4q (1.71 Sat, 20 Oct 2001 09:31:12 +0200)
     

Automake provides a set of locations where components of a package are to be installed, e.g., bindir, includedir etc. We want M4's modules to be installed in an m4 directory in the module directory, libexecdir. To this end we define in all the Makefiles a new variable, pkglibexecdir, thanks to AC_SUBST.

AC_SUBST (variable, [value]) Macro

Substitute @variable@ with its value as a shell variable in the output files. The second argument is a convenient shorthand for:

          variable=value
          AC_SUBST(variable)
          

Then we let the user chose the default modules using an additional configure option: --with-modules=list-of-modules.

     ## -------------------------- ##
     ## M4 specific configuration. ##
     ## -------------------------- ##
     AC_SUBST([pkglibexecdir], ['${libexecdir}'/$PACKAGE])
     AC_SUBST([ac_aux_dir])
     
     AC_MSG_CHECKING(for modules to preload)
       m4_pattern_allow([^m4_default_preload$])
       m4_default_preload="m4 traditional gnu"
       DLPREOPEN=
     
       AC_ARG_WITH([modules],
         [AC_HELP_STRING([--with-modules=MODULES],
                         [preload MODULES [$m4_default_preload]])],
         [use_modules="$withval"],
         [use_modules="$m4_default_preload"])
     
       DLPREOPEN="-dlpreopen force"
       if test -z "$use_modules"; then
         use_modules=none
       else
         if test "$use_modules" != yes; then
           for module in $use_modules; do
             DLPREOPEN="$DLPREOPEN -dlpreopen ../modules/$module.la"
           done
         fi
       fi
     AC_MSG_RESULT($use_modules)
     AC_SUBST(DLPREOPEN)
     

There are several new macros used here. The pair AC_MSG_CHECKING/AC_MSG_RESULT is responsible of the messages display at configure runtime:

     checking for modules to preload... m4 traditional gnu
     

     ## ------------------ ##
     ## C compiler checks. ##
     ## ------------------ ##
     AC_PROG_CC
     AC_ISC_POSIX
     AM_PROG_CC_STDC
     AC_PROG_CPP
     AC_PROG_CC_C_O
     M4_AC_CHECK_DEBUGGING
     
     # Use gcc's -pipe option if available: for faster compilation.
     case "$CFLAGS" in
       *-pipe* ) ;;
             * ) AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -pipe],
                     [m4_cv_prog_compiler_pipe],
                     [-pipe -c conftest.$ac_ext], [],
                     [CFLAGS="$CFLAGS -pipe"])
                   ;;
     esac
     
     ## ----------------------- ##
     ## Libtool initialisation. ##
     ## ----------------------- ##
     AM_ENABLE_SHARED
     AC_LIBTOOL_DLOPEN
     AC_LIBTOOL_WIN32_DLL
     AM_PROG_LIBTOOL
     AC_LIB_LTDL
     
     AC_SUBST([LTDLINCL], ["${LTDLINCL-INCLTDL}"])
     
     ## ---------------- ##
     ## Gettext support. ##
     ## ---------------- ##
     ALL_LINGUAS="cs de el fr it ja nl pl ru sv"
     AM_GNU_GETTEXT
     AC_CONFIG_FILES(po/Makefile.in intl/Makefile)
     
     if test "$USE_INCLUDED_LIBINTL" = yes; then
       AC_SUBST([INTLINCL], ['-I$(top_srcdir)/intl'])
     fi
     
     ## ------------------------ ##
     ## Other external programs. ##
     ## ------------------------ ##
     AC_PROG_INSTALL
     AC_PROG_MAKE_SET
     AC_PATH_PROG(PERL,perl)
     AC_PROG_AWK
     
     ## ------------------------- ##
     ## C headers required by M4. ##
     ## ------------------------- ##
     AC_CHECK_HEADERS(limits.h locale.h memory.h string.h unistd.h errno.h)
     AC_HEADER_STDC
     
     ## --------------------------- ##
     ## C compiler characteristics. ##
     ## --------------------------- ##
     AM_C_PROTOTYPES
     AC_C_CONST
     AC_TYPE_SIZE_T
     AC_CHECK_SIZEOF([long long int])
     
     ## --------------------------------- ##
     ## Library functions required by M4. ##
     ## --------------------------------- ##
     AC_CHECK_FUNCS(bzero calloc strerror tmpfile)
     AC_REPLACE_FUNCS(mkstemp strtol xmalloc xstrdup)
     if test $ac_cv_func_mkstemp != yes; then
       AC_LIBOBJ(tempname)
     fi
     AC_FUNC_ALLOCA
     AC_FUNC_VPRINTF
     
     AM_WITH_DMALLOC
     
     jm_PREREQ_ERROR
     
     M4_AC_FUNC_OBSTACK
     M4_AC_SYS_STACKOVF
     
     M4OBJS=
     m4_pattern_allow([^m4_getopt_h$])
     m4_getopt_h=src/getopt.h
     rm -f $m4_getopt_h
     AC_CHECK_FUNC([getopt_long], [],
         [M4OBJS="getopt1.$ac_objext getopt.$ac_objext"
         AC_CONFIG_LINKS([$m4_getopt_h:src/gnu-getopt.h])])
     AC_SUBST([M4OBJS])
     
     
     # This is for the modules
     AC_STRUCT_TM
     AC_FUNC_STRFTIME
     AC_CHECK_FUNCS(getcwd gethostname mktime uname)
     AC_CHECK_FUNCS(setenv unsetenv putenv clearenv)
     
     AC_LIB_GMP
     AM_CONDITIONAL([USE_GMP], [test "x$USE_GMP" = xyes])
     
     ## ---------------------------------- ##
     ## Make sure LTLIBOBJS is up to date. ##
     ## ---------------------------------- ##
     Xsed="sed -e s/^X//"
     LTLIBOBJS=`echo X"$LIBOBJS" | \
         $Xsed -e 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
     AC_SUBST([LTLIBOBJS])
     
     ## -------- ##
     ## Outputs. ##
     ## -------- ##
     AC_CONFIG_FILES(Makefile config/Makefile doc/Makefile m4/Makefile
                     m4/system.h:m4/system-h.in src/Makefile modules/Makefile
     		tests/Makefile examples/Makefile)
     AC_OUTPUT