Table of Contents
- Working With the GNU Autotools
- Autotools Basics
- Basic Structure of the configure.ac File
- The Package Base Directory configure.ac File
- The Project Directory configure.ac File
- Configuration Header Files
- Introduction of Automake Concepts
- The Package Base Directory Makefile.am File
- The Project Main Directory Makefile.am File
- The Source Directories Makefile.am Files
- The Test Directory Makefile.am File
- The pkg-config configuration files of a project
- Using the Correct Version of the Autotools
- Brief Tutorial on Switching from BuildTools 0.5 to 0.7
- Hints, tricks, bugs, and suggestions
Working With the GNU Autotools
Most of the COIN-OR projects use GNU autoconf, automake, and libtool (collectively, the GNU autotools) to automatically configure the source code and the compilation process for a user's computing environment. The goal is to spare users the chore of editing source and configuration files by hand, and to make the code and compilation as portable as possible.
Because the autotools support many operating systems, compilers, and other environment characteristics, they might seem somewhat complicated at first glance. However, we have tried to hide most of the details that are required to successfully use these tools by encapsulating the difficult issues and provide a COIN-OR project manager friendly layer on top of the autotools.
A good description of those tools and how they play together can be found in the Autobook, but the versions of the tools discussed there are not the most recent ones. The documentation for each tool can be found here for autoconf, automake, and libtool.
As a project manager, you will need to write the input files for the autotools: the configure.ac and Makefile.am files. Once they are written, you need to run the autotools programs to generate the configure script and Makefile.in template files. All this is described in the following sections.
The autotools will allow you to do much, much more. The goal here is simply to get you started.
The configure.ac Files
The configure script is generated by autoconf based on the configure.ac input file. Configure.ac usually contains autotools macro invocations and sh commands. To make the use of autotools easier for COIN-OR developers and to promote consistency across COIN-OR projects, the BuildTools project defines many new macros that provide many standard features. (You can examine the definitions in the file stable/0.7/coin.m4).
Basic structure of the configure.ac file
COIN-OR configure.ac files have a certain structure. Even if you've used autoconf before, you should read about the basic structure of COIN-OR configure.ac files, since we are using a number of custom defined autoconf macros.
Base directory configure.ac file
Many packages in COIN-OR use a simple configure script in the base directory of the package (e.g., the directory Coin-Clp in the directory structure example). This configure script usually does only a few tasks: create a libtool for use by the included packages, determine which COIN-OR projects are available in subdirectories, and generate the main Makefile. Details of the corresponding configure.ac file can be found here.
Package directory configure.ac files
The real configuration files are contained in the project subdirectories (such as the CoinUtils or Clp subdirectories in the directory structure example). This is where the tests for each separate project are performed. The configure.ac files here are usually more involved. Details of package directory configure.ac files can be found here.
The Makefile.am Files
Makefiles are generated by the configure script from Makefile.in template files. Makefile.in files are generated by automake from Makefile.am input files. Makefile.am files contain information on what targets are to be built (e.g., programs or libraries), what source files are required for each target, where libraries and include files should be installed, etc. One can also write regular Makefile rules that will be copied verbatim into the final Makefile. Just remember that if you want to keep portability, you're writing for the 'lowest common denominator' implementation of make.
In a typical COIN-OR project there are a number of different types of Makefile.am, depending on the purpose of the corresponding directory. Before looking at the descriptions below, please read the introduction to automake concepts.
- Base directory Makefile.am file: Even though this generates the only Makefile a typical user will use directly, it is very simple. It defines the subdirectories into which make should recurse to build the project, and it typically defines additional recursive targets (e.g., tests, which will run 'make test' in all subdirectories that have tests). Details of the package base directory Makefile.am can be found here.
- Project main directory Makefile.am file: Each project's main directory (the subdirectories under the package base directory, such as Clp or CoinUtils in the directory structure example) contains the Makefile that takes care of project-specific activities, such as defining how 'make test' is run. It also knows the source code directories into which make should recurse in order to build everything that the project must provide. Details of the main Makefile.am for a project can be found here.
- Source code directory Makefile.am files: This is where the actual build happens. Here one specifies what is to be built, what source files are required, where (and whether) the compiled files are to be installed, etc. Details of the Makefile.am files for the source code directories can be found here.
- Unit Test Makefile.am files: These also specify how to compile a program and are thus similar to a source directory Makefile.am file, but they are usually simpler. Details of the Makefile.am files for the test code directories can be found here.
- Example Makefile.in files: COIN-OR projects that generate a library should provide some example code (typically a simple main program) that demonstrates how the library can be used. It is assumed that most users of COIN-OR software will lack the skills or the environment to run the autotools; it follows, therefore, that providing a Makefile.am file for an example is pointless. It's also true that the Makefiles generated by automake are complex and generally unreadable by a human. For these reasons, project developers should provide a Makefile.in file which the configure script can process to generate a Makefile. It is recommended that the project provide a Makefile.in that produces a ''simple'' Makefile for the user that is configured for the user's system and can be easily modified for the user's own application. If you want to provide such a Makefile for your example program, have a look at existing COIN-OR projects for examples and adapt them to your needs.
Running the Autotools
First, you should make sure that you are using the correct version of the autotools.
You can run the autotools on your package by going into the package's base directory (Coin-Clp in the directory structure example) and running the BuildTools/run_autotools script. When run with no parameters, the script will examine the current directory and subdirectories for configure.ac files. For each directory found to contain a configure.ac file, the script will copy the required auxiliary files into the directory, create a temporary link to the BuildTools directory (if not existing yet), and run the autotools. You can also explicitly specify a set of directories as arguments and disable the recursion into subdirectories. The run_autotools script also observes the environment variable COIN_SKIP_PROJECTS.
Once you have a working version of your package and you can run make, you should (re)run the configure script with the --enable-maintainer-mode parameter. This will activate a number of makefile rules that simplify the maintenance of the configuration files. When you now edit a configure.ac or Makefile.am file, the corresponding autotool program will be run at the next execution of make. If necessary, the configure script will be rerun so that everything is kept up-to-date. Specific to COIN-OR, when the Dependencies file, which contains the definitions of project dependencies, has changed, the subversion svn:externals property of the base directory will be automatically updated.
A few notes of caution when maintainer mode is enabled:
- If changes to a configure.ac or Makefile.am input file introduce an error, the make for updating everything may fail. It may be necessary to rerun the autotools "by hand" after the error has been corrected, using the BuildTools/run_autotools script.
- When you make a change in a configure.ac file, make will rerun the configure script, but not recursively. If the change you made now requires recursion into a new directory, you will have to rerun the configure script by hand. To determine the options used in the most recent run of the configure script, look at the beginning of the config.log output file. Make sure that you don't use the --no-create or --no-recursion options when you rerun the script.
- The base directory Makefile will update the svn:externals property when the Dependencies file has been changed, but it will not automatically run a 'svn update' command to check out new external directories (to avoid unwanted conflicts). To check out the code for a new external dependency, run 'svn update' by hand.
Which Files Should be in the Subversion Repository?
The short answer is "Everything that's input for the autotools, or is created when the run_autotools script is run." Assume that users will not have the ability to run the autotools.
More specifically, the following files should be included in the subversion repository:
- Every configure.ac and Makefile.am file. Make sure that the svn:keywords properties are set to "Author Date Id Revision". In other words, treat them like source files.
- Every configure and Makefile.in file. These are generated by the autotools and cannot be recreated by the average user. Do not include Makefiles; these are generated when the user runs the configure script.
- In the base and project directory of the package, include config.guess, config.sub, depcomp, install-sh, ltmain.sh, and missing. These files will be copied into the directory automatically when you run BuildTools/run_autotools. For users that checkout the base directory of a project, it is sufficient to find these files in the base directory. However, for users that checkout only the project directory and want to build against installed versions of dependencies these files are also required to be present in the project directory.
Working On Your Project
If you are working on your project, you should run configure with the --enable-maintainer-mode flag. This way, changes in your configure.ac and Makefile.am files will automatically trigger execution of the autotools programs. If necessary, you can run the autotools "by hand" using the BuildTools/run_autotools script.
If you want to compile the package's code with debug information, you should use the --enable-debug parameter when you run the configure script. This will add to the compile command the parameters necessary to produce code with debugging information. It will also force the use of static libraries. (This last sidesteps a few less-than-obvious consequences of using libtool. When shared libraries are built, the libraries remain hidden in the .libs subdirectories until 'make install' is executed. Programs which depend on these libraries will most likely not run because the shared libraries cannot be found.)