Novell Home

Overview of GNU Autotools

From Developer Community

Author: Matt ryan

If you are used to Linux or UNIX, familiar with C or C++ development, or have ever downloaded and installed a source distribution that wasn't a source RPM, you probably have some familiarity with GNU Autotools. If you want to find out how they work and how they work together, what they are useful for, and how to make use of they in your application, this document is for you. It is intended to give a basic introduction to the use of the GNU Autotools toolchain, particularly on SUSE Linux.


Contents

Introduction to GNU Autotools

The term "GNU Autotools" is used to refer to a set of tools maintained by the Free Software Foundation and the GNU Project.

What GNU Autotools Are For

The GNU Autotools origins stem from the need to create software packages that are more cross-platform compatible. Thus, the reason to use the GNU Autotools in your application development is if you need the ability for your software to be properly built for multiple platforms or hardware architectures. Some people also prefer to distribute their software in source code form; likewise, some prefer to receive it in source code form. They would prefer to build the software locally on the deployment machine rather than obtain a binary version of the package. If you prefer that your target users build your software locally or if your target users prefer to build your software locally, you may want to consider using GNU Autotools for your software (although one might contend that a source RPM would be better suited in some cases).

Of course, GNU Autotools only make sense for software that needs to be compiled to run on the target platform - primarily C and C++ applications.


What GNU Autotools Are Not For

Although you can make specifications within the tools of other software packages that your software depends on, we recommend that you enforce these dependencies primarily via RPM, because doing so allows your end users to make use of RPM-based tools like YaST that can automatically resolve dependencies by selecting additional packages to install.


When Should I Use GNU Autotools?

  • If you are using a compiled language, like C or C++, you may want to use GNU Autotools to help build your application for the target platform (read on to see if any further criteria fit your situation). Interpreted languages like Perl or Python don't really fit this requirement. (Editor's Note: We would be interested to hear counterpoints in this regard if you have them.)
  • If you cannot predict the environment (operating system and/or hardware platform) that your target audience will be using, you may wish to consider using GNU Autotools, as doing so will help your product become less platform-dependent. This may be true regardless of how you distribute your software. For example, you may distribute binary RPMs, but if your application needs to run on a variety of environments, you may still want to use GNU Autotools so that someone can do a targeted build of the RPM for a specific environment. Examples of developers in this situation might include:
    • Maintainers of open source software projects that may need to be compiled on any number of operating systems or hardware architectures, obviously unknown to the maintainer
    • Developers of commercial software that may need to be built for several operating systems or hardware architectures
    • Enterprise IT developers that need to deploy software into a heterogeneous environment
  • If you prefer to distribute source only, or if your target audience prefers a source only distribution, you may want to use GNU Autotools and distribute a tarball with the source and build files included (although we would also suggest that you consider a source RPM instead).
  • If you want your software to become a part of a Linux distribution, using GNU Autotools will make it much easier for distributions to incorporate your product into their distro.


When Should I Not Use GNU Autotools?

Well, we wouldn't be so presumptuous as to tell you that you can't use GNU Autotools for a particular situation if you really want to. However, we do have some guidelines. These guidelines are based on a simple premise - use the right tool for the right job. The right job for GNU Autotools is to manage platform differences in creating targeted application builds.

  • Although it is possible to use GNU Autotools as a way to specify and enforce dependencies of your software package, we recommend that you delegate this task to RPM, which in our view is the preferred means of application package distribution on Linux. If you prefer a source distribution to a binary distribution, distribute a source RPM (which may make use of GNU Autotools within - for the purpose of creating a targeted build).
  • If your target audience prefers a binary distribution, you should probably distribute an RPM. Your target audience may prefer a binary distribution if they are a non-technical audience. They may also be technical but not be concerned about building all of their own software locally. Note: This particular item primarily refers to how you distribute your software - you may still want to use GNU Autotools as the build mechanism for your software even if you distribute RPMs.
  • If you are deploying into a homogenous environment, using GNU Autotools may be more effort than it is worth to you unless you are already familiar with them. A simple Makefile may do the trick if you only have one or two environments to worry about. This may occur, for example, in an IT environment with a single workstation platform.


Tools in the Toolchain

Historically, writers of software faced a specific problem: How to write a single software package that could be easily built on different platforms without requiring that the developer of the package consider every conceivable deployment platform. In order to solve this problem, the configure tool was born. configure would create a script that, when executed on the target platform, would configure the build so that platform inconsistencies could be addressed. Maintainers of configure would handle platform differences, leaving the developer of the software package to focus on his package specifically. From this point, new tools were created to help developers make use of configure. Autoconf specifically helped developers to generate their configure script; automake was created to help developers create the appropriate input file required by autoconf; etc.

Below is a list of all the tools in the GNU Autotools toolchain and the role of each tool in building the application.

  • aclocal - Generates local macros into aclocal.m4 to be used by automake - simplifies the creation of standard macros that automake needs to handle platform dependencies.
  • autoheader - Creates a template of #define statements in config.h.in to be used by configure that will define platform constants and other similar things.
  • libtoolize - Puts files into place that are required by libtoool.
  • automake - Generates Makefile.in from aclocal.m4, configure.ac and Makefile.am. It used to be that you had to write your own Makefile.in; automake simplifies this.
  • autoconf - Generates configure from aclocal.m4 and configure.ac.
  • configure - Builders will run this script to configure the build for the local machine. Generates Makefile from Makefile.in and config.h.in.
  • libtool - Simplifies the inclusion of dynamic libraries depending upon the platform.


Building Your Application

Toolchain Interactions

The table below diagrams the interactions between the tools and how you use them to create your executable.

Action To Take How To Accomplish Input Files Output Expected Where Used
Step 1 Create NEWS, README, AUTHORS, and ChangeLog Edited by hand by developer. May contain any pertinent text. None NEWS, README, AUTHORS, ChangeLog Step 7
Step 2 Create configure.ac Edited by hand by developer None configure.ac
  • Step 4
  • Step 6
  • Step 8
Step 3 Create Makefile.am Edited by hand by developer None Makefile.am Step 7
Step 4 Create aclocal.m4' Generated automatically by invoking aclocal configure.ac from Step 2 aclocal.m4 Steps 5 and 8
Step 5 Create config.h.in Generated automatically by invoking autoheader aclocal.m4 from Step 4 config.h.in Step 9
Step 6 Create config.guess, config.sub, and ltmain.sh Generated automatically by invoking libtoolize -c configure.ac from Step 2
  • config.guess
  • config.sub
  • ltmain.sh
Step 7
Step 7 Create Makefile.in, install-sh, missing, INSTALL, COPYING, and depcomp Generated automatically by invoking automake -ac Makefile.am from Step 3.

Also requires the presence of:

  • Files from Step 1: NEWS, README, AUTHORS, ChangeLog
  • Files from Step 6: config.guess, config.sub, ltmain.sh
Makefile.in, install-sh, missing, INSTALL, COPYING, depcomp Step 9
Step 8 Create configure Generated automatically by invoking autoconf
  • aclocal.m4 from Step 4
  • configure.ac from Step 2
configure Step 9
Step 9 Create Makefile Generated automatically by invoking configure
  • configure from Step 8
  • config.h.in from Step 5
  • Makefile.in from Step 7
Makefile Step 10
Step 10 Create executable Generated by executing make Makefile from Step 9 executable


Writing NEWS, README, AUTHORS, and ChangeLog

These files are required by automake. More correctly, these files must exist in order for automake to run successfully. The contents of these files are not really relevant to automake. You can just put placeholders, or you can put the correct contents into each (the names are pretty self-explanatory).


Writing A Basic configure.ac

There are several sections to a configure.in file and many possible instructions that you can include; however, the basics are pretty straightforward.

The first instruction in configure.in must be AC_INIT, of the format AC_INIT(file_with_main_function):

AC_INIT(fissle.cpp)

Next instruction: AM_INIT_AUTOMAKE. The format is AM_INIT_AUTOMAKE(executable_name,version):

AM_INIT_AUTOMAKE(fissle,1.0)

Note: Be sure you type AM_INIT_AUTOMAKE, not AC_INIT_AUTOMAKE. This is a mistake I make often!


Next instruction: AC_CONFIG_HEADERS. This declares config.h as our configuration-specific header file. The format is AC_CONFIG_HEADERS(header_file):

AC_CONFIG_HEADERS(config.h)


In the next section of configure.ac we declare the programs that we depend on in order to build our package. There are predefined macros for most of them.

For example, I know that I need C++ and libtool during the build stage. I include the following:

AC_PROG_CXX
AC_PROG_LIBTOOL

Generic macros like AC_CHECK_PROG make it possible for me to check the existence of programs that don't have a predefined macro.


In the next section of configure.ac we check for libraries that our package depends on. Finding these libraries will also add them to the linking path. Here's an example of including the pcre++ library, for perl-compatible regular expressions for C++:

AC_CHECK_LIB(pcre++,pcre_exec,,echo "ERROR: Required library pcre++ not found" && exit)

Note that I have to look for a function in the library, not just the library itself. This is a bit tougher in C++ if you are using a class, not a plain function. Use the strings command on a library to figure out the name of an appropriate symbol to check for.

If you use many functions in a library, you may wish to check for all of them to ensure that the library gives you the functionality you need.


The very last thing in your configure.ac is:

AC_OUTPUT(Makefile)

Here's the complete configure.ac:

AC_INIT(fissle.cpp)
AM_INIT_AUTOMAKE(fissle,1.0)
AC_CONFIG_HEADERS(config.h)

AC_PROG_CXX
AC_PROG_LIBTOOL

AC_CHECK_LIB(pcre++,pcre_exec,,echo "ERROR: Required library pcre++ not found" && exit)

AC_OUTPUT(Makefile)


This configure.ac is sufficient to generate a useful configure script. There are a lot more things you can do in configure.ac that we have not covered here. We recommend reading the GNU Autoconf Manual for complete information.


Writing A Basic Makefile.am

Here's an example of a very basic Makefile.am:

bin_PROGRAMS = fissle
fissle_SOURCES = fissle.cpp
INCLUDES = $(all_includes)
fissle_LDFLAGS = $(all_libraries)
noinst_HEADERS = 

This is pretty simple but enough to get me started. bin_PROGRAMS identifies the name of the program I'm building. From that point I specify the sources, includes, and libraries that need to be considered. In the case of includes and libraries, I tell it to use the settings from configure, if any. noinst_HEADERS will include a list of header files that are not installed with the package but are used to build my application (which is probably all of them unless I'm offering a devel package).

That's enough to get my application to build. As with configure.ac, there are a lot more things that you can do in Makefile.am than what we've covered here. We recommend reading the GNU Automake Manual for more complete information.


Ready To Go

Now that you've created your starting files, you are ready to go. Using GNU Autotools can seem daunting at first, but with a little digging you can get it figured out pretty quickly. The trick is to first understand the files that you need to begin and to put those files in place, and second, to make sure you execute the correct commands in the correct order. I was surprised how well it worked once I figured those two things out.

Of course, like we said earlier, there is an awful lot more to know than what we've covered here. We've tried to refer you to the experts when it comes to all the things you can do with the GNU Autotools. We hope that this information is enough to get you started and to be helpful in providing for you a basic overview of GNU Autotools.


For More Information

Novell® Making IT Work As One

© 2008 Novell, Inc. All Rights Reserved.