Using Player and Automake

A brief overview of how Automake works. More...

A brief overview of how Automake works.

Note:
The Player Project recommends CMake as a build system, due to its clearer syntax and cross-platform compatibility. While it's possible to use automake to create a project using player, we recommend you follow Using Player and CMake instead.
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:

Automake and 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.

Directory structure

A project directory typically contains the following subdirectories:

Player has a slightly different (and larger directory structure), which works with generally the same principles.

Configuration files

There are two main configuration files used by these tools

A brief example

Sometimes the best way to explain a topic is by showing an example. Here, we will be building a project that uses automake and autoconf to build a c++ client application. All of the files used in this example are located in examples/tutorials/automake

configure.ac

This file is used by autoconf to generate the platform configure script, and as such contains different macros for examining the system.

AC_INIT()
AM_CONFIG_HEADER(config.h)

AM_INIT_AUTOMAKE(example,0.1)

dnl Check for c
AC_PROG_CC

dnl Checks for c++
AC_LANG_CPLUSPLUS
AC_PROG_CXX

# Player C++ Library
PKG_CHECK_MODULES(PLAYERCC, playerc++)
AC_SUBST(PLAYERCC_CFLAGS)
AC_SUBST(PLAYERCC_LIBS)


AC_OUTPUT([Makefile
           doc/Makefile
           src/Makefile
          ])

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.

Note:
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.

Makefile.am

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 Makefile.

AM_CPPFLAGS = SOME_FLAGS -g
INCLUDES = -I/some_include_directory
LDFLAGS  = -L/some_lib_directory
LDADD    = -llibname

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 lib and bin.

SUBDIRS = lib bin

Build targets

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 example.

bin_PROGRAMS     = example

example_SOURCES  = example.cc
example_CPPFLAGS = $(PLAYERCC_CFLAGS)
example_LDFLAGS  = $(PLAYERCC_LIBS)

For each target you can now specify SOURCES, CPPFLAGS, LDFLAGS, and/or LDADD.

Generating documentation

To demonstrate another aspect of the Makefile.am files we will setup code to allow you to run the command make 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:

EXTRA_DIST = example.dox

doc:
        doxygen example.dox

The EXTRA_DIST is needed to indicate that the example.dox file is part of your project and should be distributed. This is useful when you package your code for distribution with the make 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 doxygen.

Generating the build scripts

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 useful.

#!/bin/sh
aclocal
autoheader
autoconf
automake --add-missing

After generating the scripts, you can run the typical configure to finish setting up the application.

Build options

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

References