GNU Autotools Managing Packages the GNU-way
Herbert Valerio Riedel GNU Project Autotools overview
Life without the Autotools
Handcrafted Makefile
Need to customize Makefile or some config header file for each platform/feature customization
Files for .tar.gz packages need to be selected for archiving manually
For each new package, you have to perform the same tedious tasks again Autotools overview
...and now with the Autotools framework
Simplify package management (build, install, uninstall, regression testing, packaging)
Simplify multiplatform support
De-facto standard for free software and open source packages But!
Using a Framework means less freedoms
Bad Autotools usage is worse than plain Makefile Autotools overview
Autotools as perceived by enduser...
Requires sh, compiler and make implementation
./configure -–help (configure switches)
./configure
make check (optionally)
make install
make clean
make uninstall Automake overview
...and on the developer's side
Requires perl, m4, make, sh, aclocal, autoheader, automake, autoconf, libtool
Developer basically writes Makefile.am and configure.in and the Autotools does the rest Autoconf
Problem
Each platform has other characteristics or features
Writing custom configurations for each platform does not scale very well Solution
Test for features (not platforms!) with the help of some supporting (feature-)testing framework. Autoconf
Operation
Autoconf processes a template file named configure.ac or configure.in and creates a configure script, which is usually shipped with the source code package.
When started on the target system, the configure script performs the tests defined in the template file. Autoconf
Structure of configure.in (recommendation) AC_INIT(hello.cc) checks for programs checks for libraries checks for typedefs checks for structures checks for compiler characteristics checks for library functions checks for system services AC_OUTPUT([Makefile ...]) Autoconf
Example project
Simple C++ project
Makefile.in, configure.in, hello.cc
Detects compiler environment and presence of ISO C99
To be processed with autoconf
To be configured with ./configure
To be finally build with make all
Clean up with make clean or make distclean Autoconf
Example configure.in AC_INIT(hello.cc) VERSION=”0.1” AC_SUBST(VERSION) AC_PROG_CXX AC_LANG_CPLUSPLUS AC_CHECK_HEADER(stdint.h,, AC_MSG_ERROR([ISO C99
Example Makefile.in CXX := @CXX@ CXXFLAGS := @CXXFLAGS@ DEFS := @DEFS@ -DVERSION=\"@VERSION@\"
.PHONY: all clean distclean
all: hello
hello: hello.cc $(CXX) $(CXXFLAGS) $(DEFS) hello.cc -o hello
clean: rm -f hello
distclean: rm -rvf hello *~ autom4te* config.* Makefile Autoconf
Example hello.cc #include
#if defined(HAVE_STDINT_H) # define __STDC_CONSTANT_MACROS # include
int main (int, char *[]) { const int64_t bigval = (INT64_C(1) << 63) - 1;
std::cout << "bigval = " << bigval << std::endl;
return 0; } Autoheader
Problem
¡ @DEFS@ becomes overpopulated
¡ Build output log with long lines hard to read
¡ Maximum supported command line length by OS Solution
¡ Pull all @DEFS@ as #define's into an header file and #include it at beginning of each source file Autoheader
Enabling use of autoheader
¡ Add AC_CONFIG_HEADER(config.h) right after AC_INIT in configure.in
¡ Add #ifdef HAVE_CONFIG_H # include
¡ Make sure to provide search path with -I. flag
¡ Run autoheader after autoconf Automake
Problem
¡ The Makefile.in template files for Autoconf's ./configure script still need to be written by hand, even though they have recurring patterns.
¡ Preparing distribution tarballs (what files to ship?) Solution
¡ Generate Makefile.in from a template Makefile.am file with Automake preprocessor. Automake
Enabling Automake support in the C++ example
¡ Add AM_INIT_AUTOMAKE(name,version) to configure.in right after AC_INIT
¡ Replace AC_CONFIG_HEADER with AM_CONFIG_HEADER
¡ Create Makefile.am
¡ touch AUTHORS ChangeLog README NEWS
¡ aclocal && autoconf && autoheader && automake –add-missing Automake
About package strictness
¡ foreign No strictness.
¡ gnu (default) Requires INSTALL, NEWS, README, COPYING AUTHORS and ChangeLog to be present.
¡ gnits Same as gnu, requires THANKS file and Performs some additional formal checks. Automake
New example configure.in AC_INIT(hello.cc) AM_INIT_AUTOMAKE(hello,0.1) AM_CONFIG_HEADER(config.h) AC_PROG_CXX AC_LANG_CPLUSPLUS AC_CHECK_HEADER(stdint.h,, AC_MSG_ERROR([ISO C99
Example Makefile.am bin_PROGRAMS = hello hello_SOURCES = hello.cc # That's all! Automake
Some more complex Makefile.am SUBDIRS = doc EXTRA_DIST = BUGS ChangeLog.old noinst_PROGRAMS = hello bin_PROGRAMS = good-bye cat++ hello_SOURCES = hello.cc util.hh util.cc good_bye_SOURCES = bye-main.cc lib.c lib.h good_bye_LDADD = -lxml good_bye_CFLAGS = -Wall -O6 cat___SOURCES = cat++.cc dog.hh dog.cc Automake
Some provided make targets
¡ make all
¡ make check
¡ make install
¡ make uninstall
¡ make clean
¡ make dist
¡ make distcheck Automake
Testsuites - make check
¡ Test result based on runtime exit code (0 = passed, 77 = ignored, else failed)
¡ Example Makefile.am Fragment: TESTS = test1 test2.sh EXTRA_DIST = test2.sh
check_PROGRAMS = test1 test1_SOURCES = test1.cc lib.cc lib.hh test1_CFLAGS = -DTEST
¢ Also used by make distcheck! Libtool
Problem
£ Building and installing (shared) libraries is highly platform dependent Solution
£ Abstract library handling with libtool Libtool
Short example # Automake native (static) library lib_LIBRARIES = libmuh.a libfoo_a_SOURCES = foo.c bar.c doo.h # Libtool based static/shared library lib_LTLIBRARIES = libkuh.la libkuh_la_SOURCES = foo.c bar.c doo.h bootstrap & autogen.sh
¤ Useful to put the aclocal, autoconf, autoheader, libtool and automake invocations into a shell script. ¤ Usually not included in source distribution tarball. (what for?) ¤ Usually kept in CVS (together with all other non-generated files) Further reading
¤ Autoconf Manual ¤ Automake Manual ¤ Libtool Manual ¤ GNU m4 Manual ¤ GNU make Manual ¤ GNU Coding Standards ¤ Software Release Practice HOWTO