Autotools 101

July 2009


I found this nice (no, I mean really good autotools tutorial. Below is what I did while reading...

Procedure 33.  Autotools Hello World

  1. Install the tools


      apt-get install autoconf libtool

  2. Create a program


      mkdir -p hw/src
      cd hw
      emacs -nw src/main.cpp:

    /*
     HelloWorld example to try packaging toolchain
     by JB 20090712
     based on numerous public domain examples
    */
    
    #include <iostream>
    
    int main (int argc, char *argv[])
    {
     std::cout << "Hello, world!\n";
     return 0;
    }
    	

  3. Create Makefile.ams

    Create Makefiles.am:

    SUBDIRS=src
    	

    and src/Makefiles.am:

    bin_PROGRAMS=HelloWorld
    HelloWorld_SOURCES=main.cpp
    	

    See the GNU Automake Manual if needed.

  4. Create configure.ac

    AC_INIT([HelloWorld],[1.0],[j.bokma@rug.nl])
    AM_INIT_AUTOMAKE([-Wall -Werror foreign])
    AC_PROG_CC
    AC_PROG_CXX
    AC_CONFIG_HEADERS([config.h])
    AC_CONFIG_FILES([Makefile src/Makefile])
    AC_OUTPUT
    	

    If you want to expand configure.ac, consider the existing tests section of the GNU Autoconf Manual.

  5. calling autoscan

    Autoscan might warn us for missing parts in configure.ac. But this time there are none.

    autoscan

  6. Calling autoreconf

    Autoreconf creates

    autoreconf --install

  7. Creating a tarbundle

    make distcheck
    { test ! -d hello-world-1.0 || { find hello-world-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-world-1.0; }; }
    test -d hello-world-1.0 || mkdir hello-world-1.0
    <snippety-snippety-snip>
    make[1]: Leaving directory `/home/jurjen/src/hw/hello-world-1.0/_build'
    { test ! -d hello-world-1.0 || { find hello-world-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-world-1.0; }; }
    =================================================
    hello-world-1.0 archives ready for distribution:
    hello-world-1.0.tar.gz
    =================================================

Procedure 34.  Internationalization with GetText

  1. Internationalization

    1. Invoking gettextize

      The gettext part of the autotools tutorial is excellent.

      gettextize
      Please use AM_GNU_GETTEXT([external]) in order to cause autoconfiguration
      to look for an external libintl.

      Please create po/Makevars from the template in po/Makevars.template.
      You can then remove po/Makevars.template.

      Please fill po/POTFILES.in as described in the documentation.

      Please run 'aclocal -I m4' to regenerate the aclocal.m4 file.
      You need aclocal from GNU automake 1.9 (or newer) to do this.
      Then run 'autoconf' to regenerate the configure file.

      You will also need config.guess and config.sub, which you can get from the CVS
      of the 'config' project at http://savannah.gnu.org/. The commands to fetch them
      are
      $ wget 'http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess'
      $ wget 'http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub'

      You might also want to copy the convenience header file gettext.h
      from the /usr/share/gettext directory into your package.
      It is a wrapper around <libintl.h> that implements the configure --disable-nls
      option.

      Press Return to acknowledge the previous 6 paragraphs.

      Do as it says: edit configure.ac, copy po/makevars.template to po/Makevars and edit that, and edit po/POTFILES.in. Also run aclocal -I m4.

    2. Calling autoconf through autoreconf

      autoreconf --install
      wget 'http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess'
      wget 'http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub'
      cp /usr/share/gettext/gettext.h src

  2. Modify the source

    #include <iostream>
    #include "config.h"
    #include <locale>
    #include "gettext.h"
    #define _(string) gettext (string)
    
    int main (int argc, char *argv[])
    {
    setlocale (LC_ALL, "");
    bindtextdomain (PACKAGE,
                    LOCALEDIR);
    textdomain (PACKAGE);
    std::cout << _("Hello, world!\n");
    return 0;
    }               
    	

  3. Localization

    cd po/
    make update-po
    msginit -l nl --input hello-world.pot

    Edit hello-world.pot

    msgfmt --statistics --check nl.po
    echo nl >> LINGUAS

  4. create another tarball

    autoreconf --install
    ./configure
    make distcheck