A brief overview of how Automake works. More...
A brief overview of how Automake works.
- Parts of this document have been adapted from Vishal Patil's c, c++ programming tips document. If you would like a more thorough treatment, I suggest you see the original document.
Table of contents:
- Directory structure
- Configuration files
- A brief example
- Generating the build scripts
- Build options
Autoconf are tools designed to help developers get rid of challenges associated with writing
Makefiles in projects. These tools help you during the development of software along with the deployment on various systems. We will be giving a cursory overview of the tools and explain how they pertains to writing your own client applications.
A project directory typically contains the following subdirectories:
- src : Contains the source code that gets compiled. Often times, the
srcfolder contains information for only one executable or libarary, but it is possible to have multiple executables per directory.
- doc : Contains the project documentation. If you use doxygen or any other program for autogenerating your documentation, it is a good idea to build a
Makefileso you can run
docin this folder to automatically generate the documentation.
Player has a slightly different (and larger directory structure), which works with generally the same principles.
There are two main configuration files used by these tools
- configure.ac : Used by
autoconfto generate a platform specific configuration script. Only one is needed per project.
- Makefile.am : Used by
automaketo generate the
Makefilein each of the source folders. Typically a project will contain a Makefile.am in each folder.
Sometimes the best way to explain a topic is by showing an example. Here, we will be building a project that uses
autoconf to build a c++ client application. All of the code for this example is include in examples/tutorial_automake.
This file is used by
autoconf to generate the platform configure script, and as such contains different macros for examining the system.
In the above sample
configure.ac the parameters passed to the AM_INIT_AUTOMAKE function represent the package name and version number respectively.
The PKG_CHECK_MODULES macro is then used to search for a file called
playerc++.pc. Most projects that use the
autotools provide users with a package config file. These files contain information about where the program has been installed on the system and information about any libraries or compiler flags that need to be used.
- If you are installing Player on a machine, you need to make sure that the PKG_CONFIG_PATH that the code installed to is included in your search path. If you are using a bash shell, you can enter the following (or something similar) in your ~/.bashrc.
# for .pc in /usr/local export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig/
AC_SUBST is then used to make the CFLAGS and LIBS variables usable to the
Makefile.am files, which we will explain in a moment.
The AC_CONFIG_FILES function needs to be given the paths of the
Makefiles that need to be generated based on the
Makefile.am in that folder.
A Makefile.am is a set of specific rules as to how variables are assigned and used in the
Makefile.am files. We will discuss some of the most common ones, but the rest are beyond the scope of the document. The following assigments are general to all targets built in the current
AM_CPPFLAGS = SOME_FLAGS -g INCLUDES = -I/some_include_directory LDFLAGS = -L/some_lib_directory LDADD = -llibname
- The AM_CPPFLAGS assignment is where you insert any c/cpp flags that you'd like the precompiler to use such as DEBUG or something similar. You can also specify compiler options here
- The INCLUDES assignment is where you insert the -I flags that you need to pass to your compiler. If the stuff in this directory is dependent on a library in another directory of the same package, then the -I flag must point to that directory.
- The LDFLAGS assignment is where you insert the -L flags that are needed by the compiler when it links all the object files to an executable.
- The LDADD assignment is where you list a long set of installed libraries that you want to link in with all of your executables. Use the -l flag only for installed libraries. You can list libraries that have been built but not installed yet as well, but do this only be providing the full path to these libraries.
If your package contains subdirectories with libraries and you want to link these libraries in another subdirectory you need to put '-I' and '-L' flags in the two variables above. To express the path to these other subdirectories, use the $(top srcdir) variable. For example if you want to access a library under 'src/libfoo' you can put something like:
INCLUDES = ... -I$(top_srcdir)/src/libfoo ... LDFLAGS = ... -L$(top_srcdir)/src/libfoo ...
on the 'Makefile.am' of every directory level that wants access to these libraries.
Also, you must make sure that the libraries are built before the directory level is built. To guarantee that, list the library directories in SUBDIRS before the directory levels that depend on it. One way to do this is to put all the library directories under a
lib directory and all the executable directories under a
bin directory and on the
Makefile.am for the directory level that contains
SUBDIRS = lib bin
For each target you can also specify specific INCLUDES, LDFLAG, and/or LDADD parameters. These are associated with how you define the build targets. In our case, we have an executable called
- The bin_PROGRAMS macro indicates which targets we would like to build. There are a variety of different ways to specify targets. The
bin_tag indicates that we would like to install the program when
installis run. We could also specify
noinst_which says not to install the program (usefull for testing tools). You can also indicate that you are building a library by lib_LTLIBRARIES, but we'll reserve talking about that until we discuss building plugin drivers.
For each target you can now specify SOURCES, CPPFLAGS, LDFLAGS, and/or LDADD.
To demonstrate another aspect of the
Makefile.am files we will setup code to allow you to run the command
doc in the doc folder and build doxygen comments. To use Doxygen to automatically generate documentation you typically type the command:
> doxygen example.dox
where example.dox is a doxygen configuration file typically generated by a tool such as
doxywizard. To accomplish the same thing with your
makefile, you can utilize the fact that you can still insert traditional
Makefile syntax into a
Makefile.am. For instance:
The EXTRA_DIST is needed to indicate that the
example.dox file is part of your project and should be distributed. This is usefull when you package your code for distribution with the
dist command. Note that the line with the doxygen command is typical
Makefile syntax and thus, you need to make sure to have a TAB right instead of spaces before the
You need to run the following commands in order to generate the build scripts. Typically, they are just grouped together into a single script called
bootstrap. We also supply some options to force certain tasks to be performed these aren't strictly necessary, but often usefull.
After generating the scripts, you can run the typical
configure to finish setting up the application.
You need to run the configure script before building the project using make. After successfully running the configure script the following options as avaliable for make
make: Builds the project and creates the executables and libraries.
clean: Cleans the project i.e removes all the executables.
install: Builds and installs the project i.e the executable is copied in the /prefix/bin,headers in /prefix/include and libraries in /prefix/lib where prefix is usually /usr/local.
uninstall: Uninstalls the project i.e removes the files added to /prefix/bin, /prefix/include and /prefix/lib directories.
dist: Creates a distribution of the project (<package-name>- <version>.tar.gz file) of the project.