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 |
The term "GNU Autotools" is used to refer to a set of tools maintained by the Free Software Foundation and the GNU Project.
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.
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.
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.
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.
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 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 |
| 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:
| Makefile.in, install-sh, missing, INSTALL, COPYING, depcomp | Step 9 |
| Step 8 | Create configure | Generated automatically by invoking autoconf |
| configure | Step 9 |
| Step 9 | Create Makefile | Generated automatically by invoking configure |
| Makefile | Step 10 |
| Step 10 | Create executable | Generated by executing make | Makefile from Step 9 | executable |
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).
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.
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.
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.
© 2008 Novell, Inc. All Rights Reserved.