Table of Contents
Autotool Tutorial
autotools automake This tutorial aims at providing basic understanding and useful usage of Autotool.
Basic information
configure script
configure script is generated by autotool. It is usually included in source code for distribution. Users can download and compile the source code themselves through 2 steps:
./configure make make install
'configure' script checks host machine for required libraries and generate Makefile, which has all the common targets. It also accepts options to specify how the compilation process should be.
./configure --help
Makefile
all: foo
foo: foo.o bar.o baz.o
.c.o:
#<tab> $(CC)...
$(CC) $(CFLAGS) -c $< -o $@
.l.c:
$(LEX) $< && mv lex.yy.c $@
clean:
-rm *.o core
This is the dependency graph:
all
|
foo
|
.-------+-------.
/ | \
foo.o bar.o baz.o
| | |
foo.c bar.c baz.c
|
baz.l
Macros
$(CC) $(CFLAGS) -c $< -o $@
'$(CC)' is the expansion of 'make' variable, which can defined using 'var=value' syntax. Default values of '$(CC)' is 'cc'.
'.c.o:' This rule can be expended to '*.o: *c', make an *.o file from every *.c file.
'$@' represents the name of the target.
'$<' represents the first dependency for the rule in which they appear.
example:
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
This rule will $(CC) (compile) all $< (.c) files to produce $@ (.o) files.
Quick start
Files to create
The files to be created manually in the source tree below are: Makefile.am, autogen.sh, configure.ac. See below for details about each files.
foobar/
m4/
src/
Makefile.am
<your source code files>
AUTHORS
COPYING
ChangeLog
Makefile.am
NEWS
README
autogen.sh
configure.ac
Prepare package
./autogen.sh
Create a separate build tree and run:
mkdir build cd build ../configure ./configure --prefix=$(pwd)/build
The procedure to run automake:
- run 'aclocal' to generate the m4-files
- run 'autoconf' to generate the configure script on the base of the configure.ac file
- run 'automake -a -c' to generate all still missing files with generic content (INSTALL and COPYING) and to generate the Makefile.in files that are used by the configure script to generate the final Makefiles
- run the generated local 'configure' script in order to create the final Makefiles (you can set the install directory via the –prefix=INSTALLPATH parameter of the script)
- run 'make' to build your programs and 'make install' to install the program in the usual or via the –prefix parameter of the configure-script defined install path
- with 'make dist' you can generate a packed source code distribution, which you can provide for download (e.g. with 'make dist-gzip' in .tar.gz format)
Writing autogen.sh
foobar/autogen.sh:
#!/bin/sh autoreconf --force --install -I config -I m4
The –force option rebuilds the configure script regardless of its timestamp in relation to that of the file configure.ac.
The option –install copies some missing files to the directory, including the text files COPYING and INSTALL.
We add -I config and -I m4 so that the tools find the files that we’re going to place in those subdirectories instead of in the project root.
Note: Don’t run autogen.sh yet. We have to write configure.ac and Makefile.am first.
Writing `configure.ac (configure.in)`
configure.ac is input to 'autoconf' to generate configure script. It copies content of configure.ac to configure, expanding macros as they occur in the input. 'configure.ac' also use shell script. It specifies the test to be carried out before 'make'.
Tests order
1. Boilerplate.
dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT([foonly], [2.0], [gary@gnu.org]) AM_INIT_AUTOMAKE([1.9 foreign])
- Options This section should include macros which add command-line options to 'configure' <code> ACARGENABLE(getenv-properties, [ –disable-getenv-properties don't set system properties from GCJ_PROPERTIES])
dnl Whether GCJPROPERTIES is used depends on the target. if test -n “$enablegetenvproperties”; then enablegetenvproperties=${enablegetenvpropertiesdefault-yes} fi if test “$enablegetenvproperties” = no; then
AC_DEFINE(DISABLE_GETENV_PROPERTIES)
fi
</code>
- Programs. Checks for programs that are either needed by the configure process, the build process, or by one of the programs being built. <code> ACPROGCC AMPROGLEX ACPROGYACC
</code>
4. Libraries. Checks for libraries come before checks for other object visible to C (or C++).
- Headers. Checks for existence of headers.
- Typedefs and structures.
- Functions. If a function is not available in a system (in a lib etc.) then it's a non-portable function. There are 3 approaches to a missing function. These approaches also apply to typedefs, structures, and global vaiables.
The first approache is to write a replacement function and conditionally compile it, or put it into an appropriately-named file and use 'ACREPLACEFUNCS'.
The second approache is used when there is a similar function with a different name. The idea here is to check for all the alternatives and and then modify your source to use whichever one might exist. The idiom here is to use break in the second argument to ACCHECKFUNCS; this is used both to skip unnecessary tests and to indicate to the reader that these checks are related. For instance, here is how libgcj checks for inetaton or inetaddr; it only uses the first one found:
AC_CHECK_FUNCS(inet_aton inet_addr, break)
Code to use the results of these checks looks something like:
#if HAVE_INET_ATON ... use inet_aton here #else #if HAVE_INET_ADDR ... use inet_addr here #else #error Function missing! #endif #endif
The third approach to non-portable functions is to write code such that these functions are only optionally used.
- Outputs: ALL Makefile of subfolders must be declared here <code> ACCONFIGFILES([Makefile src/Makefile examples/Makefile examples/atimer/Makefile examples/udpclient/Makefile examples/udpserver/Makefile ]) AC_OUTPUT
</code>
It's easy to check for too much! and that's not good.
configure.ac Macros
These macros are list in the order they should appear in configure.ac file.
Silent building
This will hide the verbose build command. It is sometime advisable not to use this for the sake of debugging.
- Passing the silent-rules option at the call to AMINITAUTOMAKE as is done with many other options; <code> ## Check for availability of this macros and use it. m4ifdef([AMSILENTRULES], [AMSILENT_RULES([yes])]) </code>
- Using the AMSILENTRULES macro directly after the initialisation;
Check for availability of libs
Writing Makefile.am (automake)
'Automake' turns 'Makefile.am' into a GNU-compliant 'Makefile.in' for use with 'configure'. Each Makefile.am' is written according to make syntax; Automake recognizes special macro and target names and generates code based on these.
==== General automake principles ====
- Odinary comments '#'s are passed through to the ouput. '##' comment is automake comment and is not procesed.
- Makefile.am can 'include' other files. Content of these files are inserted inplace of include directives. '$(top_srcdir)' indicates the top most directory of the project. '$(srcdir)' or relative path can be used to indicate current directory.
- Conditionals possible.
- '+=' will be translated to '=' in 'Makefile.in'.
Automake scans 'configure.in' before reading any 'Makefile.am'. Every 'AC_SUBST' can be accessed using @var_name@ and made available as Makefile variable.
==== Automake primaries ====
Every type of object that 'automake' understands has a special root variable name associated with it. This root is called a //primary//. Many variable names are constructed by adding various prefixes to a primary.
The contents of a primary-derived variable are treated as targets in the resulting Makefile'.
## adding prefix to primary. bin_SCRIPTS = magic-script magic-script: magic-script.in sed -e 's/whatever//' < $(srcdir)/magic-script.in > magic-script chmod +x magic-script
Primaries
simples primaries
DATA. List of verbatim files in source directory or build directory.
HEADERS. List of header files.
SCRIPTS. Executable scripts.
MANS. List of man pages.
TEXINFOS. Texinfo document not man pages.
complex primaries
PROGRAMS for programes, LIBRARIES for libraries, and LTLIBRARIES for Libtool libraries.
## programs. bin_PROGRAMS = doit doit_SOURCES = doit.c main.c ## STATIC libs lib_LIBRARIES = libzlib.a libzlib_a_SOURCES = adler32.c compress.c crc32.c deflate.c deflate.h \ gzio.c infblock.c infblock.h infcodes.c infcodes.h inffast.c inffast.h \ inffixed.h inflate.c inftrees.c inftrees.h infutil.c infutil.h trees.c \ trees.h uncompr.c zconf.h zlib.h zutil.c zutil.h ## Dynamic libs. lib_LTLIBRARIES = libzlib.la libzlib_la_SOURCES = adler32.c compress.c crc32.c deflate.c deflate.h \ gzio.c infblock.c infblock.h infcodes.c infcodes.h inffast.c inffast.h \ inffixed.h inflate.c inftrees.c inftrees.h infutil.c infutil.h trees.c \ trees.h uncompr.c zconf.h zlib.h zutil.c zutil.h
Primary-prefix
bin_ – for programs, e.g., /usr/local/bin
lib_ – where libraries are placed, e.g., /usr/local/lib
include_ – where header files are placed, e.g., /usr/local/include
pkginclude_ – e.g., /usr/local/include/foobar
noinst_ – files that will not be copied anywhere by make install
???
Header files in SOURCES are ignored (except by make dist) but can serve to make your 'Makefile.am' a bit clearer.
'configure' substitutions (variable) can't be used in a SOURCES variable. To conditionally compile files, automake conditionals or LDADD variable can be used.
bin_PROGRAMS = foo foo_SOURCES = main.c foo_LDADD = @FOO_OBJ@ foo_DEPENDENCIES = @FOO_OBJ@ EXTRA_foo_SOURCES = foo.c
Create an output variable from a shell variable. Make ACOUTPUT (configure.ac) substitute the variable variable into output files (typically one or more makefiles). This means that ACOUTPUT replaces instances of ‘@variable@’ in input files with the value that the shell variable variable has when AC_OUTPUT is called
'EXTRAfooSOURCES' lists sources which are conditionally compiled. foo_LDADD' macro is used to list other object files and libraries which should be linked into the foo program. Each program or library has several such associated macros which can be used to customize the link step; here we list the most common ones:
_DEPENDENCIES'
Extra dependencies which are added to the program's dependency list. If not specified, this is automatically computed based on the value of the program's
_LDADD'
Extra objects which are passed to the linker. This is only used by programs and shared libraries.
_LDFLAGS'
Flags which are passed to the linker. This is separate from _LDADD' to allow _DEPENDENCIES' to be auto-computed.
_LIBADD'
Like _LDADD', but used for static libraries and not programs.
You aren't required to define any of these macros.
compilation flages
Another general problem that comes up is that of setting compilation flags. Most rules have flags–for instance, compilation of C code automatically uses CFLAGS'. However, these variables are considered user variables. Setting them in Makefile.am' is unsafe, because the user will expect to be able to override them at will.
To handle this, for each flag variable, Automake introduce an AM_' version which can be set in Makefile.am'. For instance, we could set some flags for C and C++ compilation like so:
AM_CPPFLAGS
The contents of this variable are passed to every compilation that invokes the C preprocessor; it is a list of arguments to the preprocessor. For instance, -I' and -D' options should be listed here.
AM_CFLAGS
This is the variable the Makefile.am' author can use to pass in additional C compiler flags. It is more fully documented elsewhere. In some situations, this is not used, in preference to the per-executable (or per-library) _CFLAGS.
AM_LDFLAGS
This is the variable the Makefile.am' author can use to pass in additional linker flags. In some situations, this is not used, in preference to the per-executable (or per-library) _LDFLAGS.
AM_CFLAGS = -DFOR_C AM_CXXFLAGS = -DFOR_CXX
-D options
For instance, the etags.c' file which comes with Emacs can be compiled with different -D' options to produce the etags and ctags programs.
bin_PROGRAMS = etags ctags etags_SOURCES = etags.c etags_CFLAGS = -DETAGS ctags_SOURCES = etags.c ctags_CFLAGS = -DCTAGS
Multiple directories
SUBDIRS = . m4 tests
Subdirs are built in the order they appear, but cleaning rules are always run in the reverse order.
testing
check_PROGRAMS = test-program test_program_SOURCES = ...
Writing macros M4
- example /dtn/oasys.
libtools
When using prefix noinstPROGRAMS=myprog instead of binPROGRAMS, the real binary will be placed inside .libs dir. The generated executable is a 'wrapper script' which calls the binary with necessary library path. This is convenient for test running the binary in place without adding library path (LDLIBRARYPATH, etc).
- linking with libs being built: http://www.gnu.org/software/libtool/manual/html_node/Using-Automake.html
Prevent wrapper script
This requires LDLIBRARYPATH to be set.
xxx_LDFLAGS = -no-install
[td@tdfed ima_carpc]$ cat tests/io/Makemodule.am ## binary is placed in the same dir as Makefile.am so choose different name bin_PROGRAMS += tcpclient_tst tcpclient_tst_LDADD = $(top_builddir)/src/liboonet.la ## prevent the generation of executable script by libtool ## when linking with non-sys libs (newly built) ##tcpclient_tst_LDFLAGS = -no-install ## point to source dir of the lib tcpclient_tst_CPPFLAGS = -I$(top_builddir)/src tcpclient_tst_SOURCES = io/tcpclient.cpp
Using pkg-config
Frequently asked questions
My program uses library x. What do I do? The pkg-config output can easily be used on the compiler command line. Assuming the x library has a x.pc pkg-config file: cc `pkg-config --cflags --libs x` -o myapp myapp.c The integration can be more robust when used with autoconf and automake. By using the supplied PKG_CHECK_MODULES macro, the metadata is easily accessed in the build process. configure.ac: PKG_CHECK_MODULES([X], [x]) Makefile.am: myapp_CFLAGS = $(X_CFLAGS) myapp_LDADD = $(X_LIBS) If the x module is found, the macro will fill and substitute the X_CFLAGS and X_LIBS variables. If the module is not found, an error will be produced. Optional 3rd and 4th arguments can be supplied to PKG_CHECK_MODULES to control actions when the module is found or not. My library z installs header files which include libx headers. What do I put in my z.pc file? If the x library has pkg-config support, add it to the Requires.private field. If it does not, augment the Cflags field with the necessary compiler flags for using the libx headers. In either case, pkg-config will output the compiler flags when --static is used or not. My library z uses libx internally, but does not expose libx data types in its public API. What do I put in my z.pc file? Again, add the module to Requires.private if it supports pkg-config. In this case, the compiler flags will be emitted unnecessarily, but it ensures that the linker flags will be present when linking statically. If libx does not support pkg-config, add the necessary linker flags to Libs.private.
Bootstrapping
For instance, whenever you edit configure.in', you must remember to re-run aclocal in case you added a reference to a new macro. You must also rebuild configure' by running autoconf; config.h' by running autoheader, in case you added a new AC_DEFINE; and automake to propagate any new AC_SUBSTs to the various Makefile.in's. If you edit a Makefile.am', you must re-run automake. In both these cases, you must then remember to re-run config.status --recheck if configure' changed, followed by config.status to rebuild the `Makefile's.
libtoolize autoreconf… chekc them out.
An Autotools Project
Other c++ etc unsorted
Linking circularly dependent static libraries
The solution is to put the libs twice or to use group declaration:
LDFLAGS += libA.a libB.a libC.a libA.a
or
LDFLAGS += -Wl , --start-group libA.a libB.a libC.a --end-group
Resources
Autotools:
- minimal autotools: http://bec-systems.com/site/121/autotools-quick-reference
Dynamic/static libs:
- C++ shared library with template: http://stackoverflow.com/questions/7349129/compile-header-only-template-library-into-a-shared-library
Compiler process:
Debug