Contents
- Autoconf – generates configuration script from a template (configure.ac) file. Generates Makefiles from Makefile.in files.
- Automake – takes Makefile.am files as an input and generates Makefile.in files
- Libtool – handles all the requirements for building shared libraries
Adding Autotools support
Creating configure.ac
The first step in adding Autotools support to your project is to create configure.ac – template input file for Autoconf. The easiest way to create the file is to use the autoscan utility to generate it. autoscan examines the source files in the directory tree of the current directory and searches the source files for portability problems. It creates a file configure.scan.
The file generated by autoscan needs some modifications:
- Edit the line
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
to include the name of the program or library, its version and the email to which users should send bug reports.
- Add an invocation to AM_INIT_AUTOMAKE([OPTIONS]), it is required for the proper operation of the generated Makefiles.
- List all Makefiles that have to be created in the AC_CONFIG_FILES macro, like below:
AC_CONFIG_FILES([Makefile src/Makefile])
- Optional: If you are building a library, add AC_PROG_RANLIB.
- Optional: If you are using additional local Autoconf macros, specify their location: AC_CONFIG_MACRO_DIR(dir).
Makefile.am files
Each directory in the source tree must have a Makefile.am file. These files define variables, determining what needs to be built (executable, library), source files, installation location, etc.
The top level Makefile.am must specify which sub-directories are to be built, using the SUBDIRS variable:
SUBDIRS = list of sub-driectories
Binary Executable
bin_PROGRAMS = APPNAME INCLUDES = \ -I$(prefix)/include\ -I$(top_srcdir)/include APPNAME_SOURCES =\ SourceFile1\ SourceFileN APPNAME_LDFLAGS = \ -L$(prefix)/lib APPNAME_LDADD = \ $(PACKAGE_LIBS)\ -lLibrary1\ -lLibraryM
The bin_PROGRAMS variable specifies that we want to built a program, named APPNAME. It will be installed in the bin directory by make install.
The INCLUDES variable – the old name for AM_CPPFLAGS, used to add include paths, prefixed by -I.
The APPNAME_SOURCES variable specifies the source files, used to build the executable.
The APPNAME_LDFLAGS variable defines the flags that need to be passed to the linker. Usually -L flags to add a library search path.
The APPNAME_LDADD variable defines the libraries that the program links to. You can specify:
- A library reference -lLIBNAME
- A relative path to a static library ../LIB/PATH/libLIBNAME.a
Note: APPNAME should be replaced with the name of the program.
Static Library
Static libraries contain object code. They are linked with the application (executable) and become part of it. Static libraries have .a extension.
lib_LIBRARIES = libLIBNAME.a INCLUDES = \ -I$(prefix)/include\ -I$(top_srcdir)/include library_includedir = $(includedir)/LIBNAME library_include_HEADERS=\ $(top_srcdir)/include/LIBNAME/Header1.h\ $(top_srcdir)/include/LIBNAME/HeaderN.h libLIBNAME_a_SOURCES=\ SourceFile1\ SourceFileN
The lib_LIBRARIES variable specifies that we want to build a static library (.a) and defines it’s name. It will be installed in the lib directory by make install.
The INCLUDES variable – the old name for AM_CPPFLAGS, used to add include paths, prefixed by -I.
library_includedir specifies the directory where the header files (public interface) will be installed.
library_include_HEADERS lists the header files (public interface) that need to be copied to the library_includedir.
Additional arguments can be passes to the commpiler, using AM_CFLAGS, AM_CPPFLAGS, AM_CXXFLAGS variables.
The libLIBNAME_a_SOURCES variable specifies the source files, used to build the target.
Note: LIBNAME should be replaced with the name of the library without the lib prefix (i.e. dl).
Dynamic Library
Dynamic libraries are called shared objects (.so) in Linux. They are referenced by applications (executables), but do not become part of them. Dynamic libraries can be:
- linked – must be available during the link phase. The application cannot start without the library.
- loaded during execution (aka plug-ins), using dlopen on UNIX-like operating systems. The application can start in the absence of dynamically loaded libraries.
lib_LTLIBRARIES = libLIBNAME.la INCLUDES = \ -I$(prefix)/include\ -I$(top_srcdir)/include library_includedir = $(includedir)/LIBNAME library_include_HEADERS=\ $(top_srcdir)/include/LIBNAME/Header1.h\ $(top_srcdir)/include/LIBNAME/HeaderN.h libLIBNAME_la_SOURCES=\ SourceFile1\ SourceFileN libLIBNAME_la_LDFLAGS = \ -L$(prefix)/lib libLIBNAME_la_LIBADD=\ $(PACKAGE_LIBS)\ -lLibrary1\ -lLibraryM
The lib_LTLIBRARIES variable specifies that we want to build a dynamic library (.a) and defines it’s name. It will be installed in the lib directory by make install.
The INCLUDES variable – the old name for AM_CPPFLAGS, used to add include paths, prefixed by -I.
The libLIBNAME_la_SOURCES variable specifies the source files, used to build the target.
The libLIBNAME_la_LDFLAGS variable defines the flags that need to be passed to the linker. Usually -L flags to add a library search path.
The libLIBNAME_la_LIBADD variable defines the libraries that this library depends on. You can specify:
- A library reference -lLIBNAME
- A relative path to a static library ../LIB/PATH/libLIBNAME.a
Note: LIBNAME should be replaced with the name of the library without the lib prefix (i.e. dl).
Building
The commands that need to be executed to prepare a project for building are shown in the diagram below. The input files of each command are listed on the left side and the output is on the right.
aclocal libtoolize autoconf autoheader automake --add-missing ./configure --prefix=/target/dir (/usr/local by default) make make install
These are a lot of commands, especially when working on a big project, having several libraries and executables – building the full source tree becomes a laborious process. I like to use a manual makefile to simplify the build. Imagine having a project with one application and two libraries. It’s directory structure is:
bin | The output applications will be installed in this folder. |
include | The output header files will be installed in this folder. |
lib | The output libraries (.so, .a) will be installed in this folder. |
source | Parent source folder |
source/application | Source code of the application |
source/library | Source code of the first library |
source/other_library | Source code of the second library |
Makefile | The master makefile, listed below |
A master makefile, simplifing the build process:
topdir=$(shell pwd) subdirs=\ ./source/library/\ ./source/other_library/\ ./source/application/ all: @echo "Valid targets are:" @echo " make prepare" @echo " make build" @echo " make clean" prepare: for dir in $(subdirs); do \ echo "$$dir" && cd $$dir && aclocal && autoconf && libtoolize && autoheader && automake -a && cd $(topdir);\ done for dir in $(subdirs); do \ cd $$dir && ./configure --prefix=$(topdir) && cd $(topdir);\ done clean: for dir in $(subdirs); do \ make -wC $$dir clean;\ done build: application application: | library other_library make -wC ./source/application/ make -wC ./source/application/ install library: make -wC ./source/library/ make -wC ./source/library/ install other_library: make -wC ./source/other_library/ make -wC ./source/other_library/ install
The sample make file has three targets:
- prepare – prepares the project by running aclocal, autoconf, automake and configuring each target. The prefix is the current folder.
- build – builds the targets, the dependencies between them should be defined manually.
- clean – cleans the targets.
Leave a Reply