Пример использования GNU autotools
The GNU autotools programs (autoconf, automake and libtool), which are used for making software portable between Unix-like operating systems, have been around for more than fifteen years now, but their use is still regarded by many programmers to be a dark art. It's fair to say that they aren't the most straightforward tools to become accustomed to, and their awkwardness has spawned the creation of at least one competing build system.
Nevertheless, as far as open-source software goes, autoconf and automake are still the main game in town, and for anyone who wants to hack around in this area, becoming familiar with these tools is essential.
This series of tutorials is designed to provide an introduction to these tools by way of simple examples.
We'll start off with a very simple Hello World program, in plain C:
#include
int main(int argc,char **argv) {
printf("Hello world\n");
}
Create a directory called hello and within that, a subdirectory called src:
mkdir -p hello/src
The topmost directory, hello will contain the entire package, and src will be where we place the source code. So now, take the snippet of c-code above, and save it in the file hello/src/hello.c.
automake uses templates with the name Makefile.am to build Makefile.in templates for autoconf to process. You will need to create a Makefile.am file within every directory in your package that automake will perform its work in. So, for this example, create the following files.
hello/src/Makefile.am:
bin_PROGRAMS = hello
hello_SOURCES = hello.c
Some explanation is required here. Automake rules take the form of target_primary. So, above, where we have the rule bin_PROGRAMS, we are specifying the list of programs that we are building that will be played in the bin directory, when installed. Similarly, we could have used sbin_PROGRAMS for any programs that we were building that we wish to place in the sbin directory.
The PROGRAMS primary will then look for source files from which it can be built. Since our target program is called hello, we specify a list of sources (separated by spaces; in the above example, we only have the one source file, hello.c) using the target hello_SOURCES.
hello/Makefile.am:
SUBDIRS = src
SUBDIRS is a special variable that lists all of the subdirectories that automake must process. If you were to have any subdirectories underneath hello/src, then you'd also include a SUBDIRS line in your hello/src/Makefile.am file, listing each of them.
Now, create hello/configure.ac with the following contents:
AC_INIT(src/hello.c)
AM_INIT_AUTOMAKE(hello,0.0.1)
AC_PROG_CC
AC_PROG_INSTALL
AC_OUTPUT(
Makefile
src/Makefile
)
configure.ac is autoconf's primary configuration file, which uses the M4 macro processing language. We'll start looking at each of these directives from the top. AC_INIT must always be the first directive called; it takes one argument, the name of any one file within the source tree. This is used to confirm that the location of the source actually exists, when the configure script is eventually run.
AM_INIT_AUTOMAKE is used only when you're using automake with autoconf; its two arguments are the name of the program you're building and the version number.
AC_PROG_CC is a macro that tells configure to look for a C compiler. When run, it will first look at the contents of the CC environment variable, and if this is empty, it will test for the presence of gcc and then fall back to cc if necessary. Should you wish autoconf to test for the presence of a C++ compiler, use AC_PROG_CXX.
AC_PROG_INSTALL looks for a BSD-compatible install program within the PATH. If it finds one, then it sets the INSTALL output variable to point to it; if it doesn't, then it sets the variable to point at install-sh in your topmost source directory. automake will automatically create this file for you; if you're only using autoconf, then you'll need to provide an install-sh script yourself. We do not need to give the --add-missing flag next time we run automake (eg, after modifying Makefile.am).
The final statement, AC_OUTPUT lists the files that the configure script should create when it is run; in this case, two Makefiles, one in each directory. This should always be the last directive in the configure.ac file.
Now, from within the hello directory, run the following:
aclocal
touch NEWS README AUTHORS ChangeLog
automake --add-missing
autoconf
aclocal should be run every time you update configure.ac; it will update the aclocal.m4 file, which provides the macros needed to build your configure script.
automake will process the Makefile.am files, and build Makefile.in files from them, for autoconf to use. We give it the --add-missing so that it will generate a number of files that it requires to be present (COPYING, INSTALL, and the shell scripts install-sh and missing). It also requires the files NEWS, README, AUTHORS and ChangeLog, but it cannot create these itself, so we touch them to create empty files; feel free to enter your own information into them.
Running autoconf will build Makefile.in files from the Makefile.am files, and will create a configure script. You'll be familiar with this script from the many free software packages that use autotools.
At this point, the program is ready for compilation:
./configure
make
make install
The configure script can be given a number of options, and you can see many of these by running it with --help. One very common option is --prefix, which tells configure that you want it installed somewhere other than the default location (/usr/local):
./configure --prefix=/opt/hello
If you'd like to make a tarball for distribution, you can run:
make dist
...and you'll be left with the file hello-0.0.1.tar.gz in the top-level directory, which will contain all the source code and autotools scripts needed to compile up the program independently of your main directory.
There are also other packaging options available; make dist-zip will use zip to create an archive; make dist-shar will create a shell archive (ie, the entire distribution in one shellscript); make dist-bzip2 will make a bzip2 tarball and make dist-tarZ will use the old Unix compress command to compress the tar file.
So, we're now at the end of this first lesson. For further practice with GNU autotools, try writing a more complex program that requires several source files. Try copying the hello-0.1.tar.gz archive to a completely different Unix platform and compile it up there. Also, investigate some of the options that the configure script provides.