Build Systems with
autoconf and libtool
    Benny Siegert ‹bsiegert@gmail.com›
 The MirOS Project (http://www.mirbsd.org)
...
Contents
1. Theory
 a) Introduction: a history lesson
 b) Presentation of components
2. Practice
 a) A concrete example
 b...
Make les
‣ since Version 7 AT&T Unix (ca 1977)

‣ Targets = lenames
  with dependencies and compiler commands
‣ “Phony” le...
… end of story?
                  Problem: Options
‣ compiler ags, conditionals

‣ paths: headers, installation directory?...
Other build systems
‣ imake (X11): Imake le + cpp ➝ Make le

  ‣ a nightmare in practice

  ‣ Xorg now uses autotools, the...
The GNU build system
‣ almost everywhere today (good!)

‣ easy to use:

    % ./configure ; make ; make install
‣ But: few...
Introducing
 autotools
con gure
Make le.in                                  Make le
                   con g.status
con g.h.in                   ...
autoconf
con gure.ac              m4                con gure
 aclocal.m4


  ‣ you don‘t actually write con gure yourself
...
autoheader
con gure.ac                            con g.h.in


  ‣ creates a template for con g.h

  ‣ con g.h contains C ...
automake
Make le.am                             Make le.in


  ‣ creates a portable Make le
    from a simpli ed descripti...
aclocal
*.m4                                      aclocal.m4

‣ part of automake

‣ tells autoconf about local macros,
  l...
pkgcon g
                                           CFLAGS
   *.pc
                                             LIBS

‣ ma...
libtool
command                                   different
                                         command

‣ shared libr...
Others

autom4te: m4 wrapper used by autoconf
 ‣ Weird problems: delete autom4te.cache

autoscan: automatically create con...
Part 2
Practice
Example source code
#include <stdio.h>
#include "hello.h"

void hello()                      hello.c
{
   printf("Hello Wo...
Traditional Make le
hw: main.o libhello.a
        cc -o hw main.o libhello.a

libhello.a: hello.o
       ar cru libhello.a...
Make le using libtool
hw: main.lo libhello.la
        ./libtool --mode=link cc -o hw main.lo libhello.la

libhello.la: hel...
autoconf + automake
   ‣ here: source code moved to src/

   ‣ call autoreconf -v -i

AC_INIT(hw, 0.1)
AM_INIT_AUTOMAKE(fo...
Using con g.h
AC_INIT(hw, 0.1)
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS(config.h)                  con gure.ac
[…]

      ‣ call...
Features we have
‣ uses user‘s CC and CFLAGS

‣ can be built outside the sources

‣ installation (via make install), unins...
libtool!
‣ goal (as before): make libhello a shared library



‣ libtool is created by con gure
    (AC_PROG_LIBTOOL macro...
[…]
AC_PROG_CC
AC_STDC_HEADERS                         configure.ac
AC_PROG_LIBTOOL
[…]

ACLOCAL_AMFLAGS = -I .
           ...
Replacement variables
‣ a variable is set to a value in con gure

‣ AC_SUBST(variable) replaces @variable@
  by its value ...
current:revision:age
‣ version info for libtool libraries

‣ three numbers ∈ ℕ

‣ current: current API revision

‣ revisio...
‣ If you don‘t touch any function prototypes:
  increment revision

‣ a function was added:
  increment current and age, s...
[…]
LIBHELLO_CURRENT=1
LIBHELLO_REVISION=0
LIBHELLO_AGE=1

LIBHELLO_VER=$LIBHELLO_CURRENT:
$LIBHELLO_REVISION:$LIBHELLO_AG...
Advanced stuff
Checking headers
    ‣ AC_CHECK_HEADERS checks if a header le is
       found and if it works
    ‣ If another header must...
arguments to con gure
‣ additional features (--enable-feature) or

  use of external packages (--with-package)
‣ AC_ARG_EN...
Example
[…]
AC_ARG_ENABLE([debug],
    AS_HELP_STRING([--enable-debug],
       [Enable debugging code (default=no)]),
    ...
More complex example
AC_ARG_WITH([glib2],
   AS_HELP_STRING([--with-glib2], [Enable support for glib 2.0
@<:@default=auto@...
Conditional compile
   ‣ No portable “if” statement in Make les,
      use automake conditionals
   ‣ decision is taken at...
How not to do it
Bake le
‣ automake replacement, used by wxWidgets

‣ pkgsrc has patched wxWidgets Make les so
  that they use libtool. The...
wx-con g
     ‣ very complex con g script instead of a .pc le

     ‣ has to clean up behind con gure:
# We evidently can'...
“List of platforms“
‣ autoconf‘s goal is to help you get rid of long
  lists of platforms and corresponding options.
‣ Yet...
a2ps Make les
‣ Last release (2.13b) in 2000

‣ uses autoconf 2.14a that was never officially
    released
‣ does not use ac...
Conclusion
‣ It is a good thing that so many projects use
  autotools – only one build system to learn
‣ you cannot write a portable ...
My golden rules
1. Don‘t try to reinvent the wheel.
2. Not everyone uses Linux i386 with gcc
   and GNU make.
3. Don‘t har...
Thank you
     for your attention!

Further Reading
‣ slides on http://www.slideshare.net/bsiegert

‣ info pages

‣ ”autot...
Upcoming SlideShare
Loading in...5
×

Build Systems with autoconf, automake and libtool [updated]

5,194
-1

Published on

Talk held at FOSDEM 2010

Published in: Technology
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,194
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
108
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Build Systems with autoconf, automake and libtool [updated]

  1. 1. Build Systems with autoconf and libtool Benny Siegert ‹bsiegert@gmail.com› The MirOS Project (http://www.mirbsd.org) FOSDEM 2010
  2. 2. Contents 1. Theory a) Introduction: a history lesson b) Presentation of components 2. Practice a) A concrete example b) Bad practices 3. Conclusion
  3. 3. Make les ‣ since Version 7 AT&T Unix (ca 1977) ‣ Targets = lenames with dependencies and compiler commands ‣ “Phony” lenames like “install” # extremely simple Makefile foo: foo.o cc -o foo foo.o foo.o: foo.c cc -c -o foo.o foo.c install: foo install -m 555 foo /usr/local/bin
  4. 4. … end of story? Problem: Options ‣ compiler ags, conditionals ‣ paths: headers, installation directory? ‣ user must be able to adjust these ‣ manually editing Make les today? unacceptable!
  5. 5. Other build systems ‣ imake (X11): Imake le + cpp ➝ Make le ‣ a nightmare in practice ‣ Xorg now uses autotools, they know why ‣ Schily make (J?rg Schilling, cdrtools) ‣ >300 Make le fragments, one per platform ‣ does not work with BSD make ‣ bsd.prog.mk etc (BSD): platform dependent
  6. 6. The GNU build system ‣ almost everywhere today (good!) ‣ easy to use: % ./configure ; make ; make install ‣ But: few developers understand it ‣ more and more “easier” alternatives (cmake) ‣ Is it really too complicated? — No, because a portable build system is difficult!
  7. 7. Introducing autotools
  8. 8. con gure Make le.in Make le con g.status con g.h.in con g.h *.in * ‣ gets options: target dir, compiler ags, paths, modules, etc. ‣ searches for libraries, headers, paths ‣ creates con g.status ‣ con g.status handles replacement variables (e.g. CC, CFLAGS, LIBS)
  9. 9. autoconf con gure.ac m4 con gure aclocal.m4 ‣ you don‘t actually write con gure yourself ‣ con gure.ac contains macro calls to be converted into a shell script ‣ Macros that are not part of autoconf come from aclocal.m4 ‣ Documentation: info autoconf (read it!)
  10. 10. autoheader con gure.ac con g.h.in ‣ creates a template for con g.h ‣ con g.h contains C preprocessor symbols for options, e.g. HAVE_FOO_H ‣ Source code: #include “con g.h” at the start of each le ‣ Documentation: info autoheader
  11. 11. automake Make le.am Make le.in ‣ creates a portable Make le from a simpli ed description ‣ Make le.am is short and simple ‣ Make le.in looks horrendously complex (don‘t touch it then) ‣ Documentation: info automake
  12. 12. aclocal *.m4 aclocal.m4 ‣ part of automake ‣ tells autoconf about local macros, like those from automake ‣ only those actually used are put into aclocal.m4 ‣ acinclude.m4 is for your own macros ‣ Documentation: info aclocal
  13. 13. pkgcon g CFLAGS *.pc LIBS ‣ makes nding and using shared libs easier ‣ replaces *-con g scripts (gtk-con g etc.) ‣ PKG_CHECK_MODULES(FOO, glib2.0 >= 2.8.0) sets FOO_CFLAGS, FOO_LIBS ‣ if you are writing a library, consider distributing a .pc le for it ‣ Dokumentation: man pkgcon g
  14. 14. libtool command different command ‣ shared library support for all platforms ‣ encapsulates platform-speci c commands ‣ you pretend you are building a static library with .la suffix (so-called libtool library) ‣ you pre x commands with libtool --mode=foo, libtool executes different, adapted commands ‣ Documentation: info libtool (except Mac OS)
  15. 15. Others autom4te: m4 wrapper used by autoconf ‣ Weird problems: delete autom4te.cache autoscan: automatically create con gure.ac libtoolize, gettextize: add les for libtool or gettext autoreconf: regenerate necessary les
  16. 16. Part 2 Practice
  17. 17. Example source code #include <stdio.h> #include "hello.h" void hello() hello.c { printf("Hello World!n"); } void hello(); hello.h #include "hello.h" int main(int argc, char **argv) { main.c hello(); return 0; }
  18. 18. Traditional Make le hw: main.o libhello.a cc -o hw main.o libhello.a libhello.a: hello.o ar cru libhello.a hello.o ranlib libhello.a .SUFFIXES: .c .o .c.o: cc -c -o $@ $< clean: rm -f hw main.o hello.o libhello.a
  19. 19. Make le using libtool hw: main.lo libhello.la ./libtool --mode=link cc -o hw main.lo libhello.la libhello.la: hello.lo ./libtool --mode=link cc -rpath /usr/local/lib -o libhello.la hello.lo .SUFFIXES: .c .lo .c.lo: ./libtool --mode=compile cc -c -o $@ $< clean: ./libtool --mode=clean rm -f hw main.lo hello.lo libhello.la
  20. 20. autoconf + automake ‣ here: source code moved to src/ ‣ call autoreconf -v -i AC_INIT(hw, 0.1) AM_INIT_AUTOMAKE(foreign) AC_PROG_CC AC_STDC_HEADERS con gure.ac AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT SUBDIRS = src Make le.am bin_PROGRAMS = hw hw_SOURCES = main.c hello.c hello.h src/Make le.am
  21. 21. Using con g.h AC_INIT(hw, 0.1) AM_INIT_AUTOMAKE AC_CONFIG_HEADERS(config.h) con gure.ac […] ‣ call autoheader (done by autoreconf ) ‣ To use con g.h: add this to the top of every .c le #ifdef HAVE_CONFIG_H #include "config.h" #endif
  22. 22. Features we have ‣ uses user‘s CC and CFLAGS ‣ can be built outside the sources ‣ installation (via make install), uninstall ‣ user can specify target directory ‣ dependency tracking (can be disabled) ‣ create a tarball (make dist) ‣ make clean
  23. 23. libtool! ‣ goal (as before): make libhello a shared library ‣ libtool is created by con gure (AC_PROG_LIBTOOL macro) ‣ copy libtool.m4 and ltmain.sh from the libtool sources (or use libtoolize --copy) ‣ nally call autoreconf -v -i
  24. 24. […] AC_PROG_CC AC_STDC_HEADERS configure.ac AC_PROG_LIBTOOL […] ACLOCAL_AMFLAGS = -I . Makefile.am SUBDIRS = src bin_PROGRAMS = hw hw_SOURCES = main.c hw_LDADD = libhello.la src/Makefile.am lib_LTLIBRARIES = libhello.la libhello_la_SOURCES = hello.c hello.h
  25. 25. Replacement variables ‣ a variable is set to a value in con gure ‣ AC_SUBST(variable) replaces @variable@ by its value in output les ‣ automake de nes variable for us in Make les ‣ Goal here: version info for libhello should be set by con gure ‣ add -version-info to libhello‘s LDFLAGS
  26. 26. current:revision:age ‣ version info for libtool libraries ‣ three numbers ∈ ℕ ‣ current: current API revision ‣ revision: bug xes etc. without any API changes ‣ age: to how many API revisions are we backwards compatible?
  27. 27. ‣ If you don‘t touch any function prototypes: increment revision ‣ a function was added: increment current and age, set revision to 0 ‣ function prototype changed or removed: increment current, set age and revision to 0
  28. 28. […] LIBHELLO_CURRENT=1 LIBHELLO_REVISION=0 LIBHELLO_AGE=1 LIBHELLO_VER=$LIBHELLO_CURRENT: $LIBHELLO_REVISION:$LIBHELLO_AGE con gure.ac AC_SUBST(LIBHELLO_VER) AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT lib_LTLIBRARIES = libhello.la libhello_la_SOURCES = hello.c libhello_la_LDFLAGS = src/Make le.am -version-info ${LIBHELLO_VER}
  29. 29. Advanced stuff
  30. 30. Checking headers ‣ AC_CHECK_HEADERS checks if a header le is found and if it works ‣ If another header must be included before, use the fourth parameter ‣ ex: sys/mount.h depends on sys/param.h […] AC_CHECK_HEADERS([sys/param.h sys/mount.h], [], [], [#ifdef HAVE_SYS_PARAM_H #include <sys/param.h> con gure.ac #endif ]) […]
  31. 31. arguments to con gure ‣ additional features (--enable-feature) or use of external packages (--with-package) ‣ AC_ARG_ENABLE and AC_ARG_WITH, work the same way ‣ Arguments: name, help string, and two shell fragments (if arg given, if omitted) ‣ AS_HELP_STRING formats the help string
  32. 32. Example […] AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [Enable debugging code (default=no)]), [enable_debug=$enableval], [enable_debug=no]) con gure.ac if test "x$enable_debug" = xyes; then AC_DEFINE(DEBUG, 1, [Enable debugging code]) fi […] ‣ AC_DEFINE: sets a preprocessor symbol (in con g.h)
  33. 33. More complex example AC_ARG_WITH([glib2], AS_HELP_STRING([--with-glib2], [Enable support for glib 2.0 @<:@default=auto@:>@]), [with_glib2=$withval], [with_glib2=auto]) if test "x$with_glib2" != xno; then PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.8], [have_glib2=yes], [have_glib2=no]) else have_glib2=no fi if test "x$with_glib2" = xyes -a "x$have_glib2" = xno; then AC_MSG_ERROR([Library requirements (glib-2.0 >= 2.8) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]) fi if test "x$have_glib2" = xyes; then AC_DEFINE([HAVE_GLIB2], [1], [Define if you have the glib2 library.]) fi
  34. 34. Conditional compile ‣ No portable “if” statement in Make les, use automake conditionals ‣ decision is taken at con gure time using the test from the second argument […] AM_CONDITIONAL(DEBUG, con gure.ac [test "x$enable_debug" = xyes]) […] […] if DEBUG hw_SOURCES += debugging.c else src/Make le.am # something else endif
  35. 35. How not to do it
  36. 36. Bake le ‣ automake replacement, used by wxWidgets ‣ pkgsrc has patched wxWidgets Make les so that they use libtool. The patch is 3 MiB. ‣ example Bake le, from the tutorial: <?xml version="1.0"?> <makefile> <include file="presets/simple.bkl"/> <exe id="hello" template="simple"> <sources>hello.c</sources> </exe> </makefile>
  37. 37. wx-con g ‣ very complex con g script instead of a .pc le ‣ has to clean up behind con gure: # We evidently can't trust people not to duplicate things in # configure, or to keep them in any sort of sane order overall, # so only add unique new fields here even if it takes us a while. […] # This is not a licence # for sloppy work elsewhere though and @GUI_TK_LIBRARY should # be fixed. […] # of course, this duplication is bad but I'll leave to somebody else the care # of refactoring this as I don't see any way to do it - VZ. # This (and the other cruft to support it) should be removed with # reference to the FIXME above when configure stops piping us a slurry # of options that need to be decomposed again for most practical uses - RL.
  38. 38. “List of platforms“ ‣ autoconf‘s goal is to help you get rid of long lists of platforms and corresponding options. ‣ Yet, some con gures manage to do this. case "${host}" in […] *-*-openbsd*) USE_BSD=1 USE_OPENBSD=1 AC_DEFINE(__OPENBSD__) AC_DEFINE(__BSD__) DEFAULT_DEFAULT_wxUSE_GTK=1 ;; *) AC_MSG_ERROR(unknown system type ${host}.) esac
  39. 39. a2ps Make les ‣ Last release (2.13b) in 2000 ‣ uses autoconf 2.14a that was never officially released ‣ does not use aclocal but: ## I use special autoconf/make macros ACLOCAL_AMFLAGS = --version >/dev/null && cat m4/*.m4 >aclocal.m4 ‣ comes with its own version of automake in 17 (!) m4 les
  40. 40. Conclusion
  41. 41. ‣ It is a good thing that so many projects use autotools – only one build system to learn ‣ you cannot write a portable build system from scratch – so don‘t try ‣ writing Make les with automake is not that complicated ‣ automake replacements complicate life for porters and contributors ‣ a good build system even runs on an “unknown” system
  42. 42. My golden rules 1. Don‘t try to reinvent the wheel. 2. Not everyone uses Linux i386 with gcc and GNU make. 3. Don‘t hardcode things that can be tested. 4. The user must be able to regenerate your autoconf infrastructure. 5. Don‘t change any generated les.
  43. 43. Thank you for your attention! Further Reading ‣ slides on http://www.slideshare.net/bsiegert ‣ info pages ‣ ”autotools mythbuster“: http://www. ameeyes.eu/autotools-mythbuster/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×