分类: LINUX
2009-02-17 12:46:30
The automake and autoconf tools can be used to manage C++ projects under Unix. They should save a lot of time compared to make and configure, while ensuring that your project is structured according to GNU standards.
However, it is difficult for beginners to get started. Hopefully, this tutorial will provide enough information for C++ programmers who are new to Unix to create their first C++ projects, while gaining a superficial understanding of what the tools are doing.
I am not an expert on automake and autoconf, so I welcome constructive advice on this tutorial. If you find problems with the examples, please try to provide patches.
The make tool can be used to manage multi-file projects. make uses the Makefile file in your project folder, which lists the various compiling and linking steps, targets, and dependencies. make is well explained in .
A configure script can be used to aid cross-platform compiling. A suitable configure script should interpret a Makefile.in file and then create a platform-specific Makefile file. It will do this after performing several tests to determine the characteristics of the platform.
This allows a user to type './configure' and then 'make' to compile a project on his platform.
Obviously most well-written Makefiles and configure scripts will look very similar. In fact, GNU provide guidelines about what should be in these files. Therefore, GNU created automakeand autoconf to simplify the process and ensure that the Makefile and configure script conform to GNU standards.
Here is a brief explanation of how these tools are used. You can see examples of the files used by these tools in the Examples Files section.
Note: These tools use the m4 programming language. aclocal adds aclocal.m4 to your project directory, which contains some m4 macros which are needed.
autoconf
autoconf looks for a file called configure.ac (or, previously, configure.in). It then creates the configure script, based on the macros which it finds.
Whenever you add a macro to configure.ac, you should run aclocal as well as autoconf, because aclocal scans configure.ac to find which macros it should provide.
Lines which every configure.ac should have
Every configure.ac should have lines like the following:
AC_INIT(hello.cc) AM_INIT_AUTOMAKE(hello,0.1) AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL AC_OUTPUT(Makefile)The AC_INIT macro can take any source file as an argument. It just checks that the file is there, which should, in turn, mean that the source directory is there.
The AM_INIT_AUTOMAKE line adds several standard checks. It takes the program name and version number as arguments.
AC_PROG_CC indicates that the source code may be in C. If the source code is C++ then we also need AC_PROG_CXX.
AC_PROG_INSTALL will generate an install target so that users may just type 'make install' to install the software.
AC_OUTPUT indicates the name of the Makefile which will be generated.
Using a Config Header
The AM_CONFIG_HEADER(config.h) line indicates that you will be using a config.h file. autoconf will then need a config.h.in file, which it processes to create the config.h file. This is #included by your source code and provides a way for people to customise the configuration for their platform, via #defines.config.h.in can be generated automatically with the autoheader tool.
However, you need a stamp-h file in your project to ensure that automake regenerates config.h from config.h.in. Type 'touch stamp-h' to add this file to your project.
automake
automake looks for a file called Makefile.am. It then creates a Makefile.in, based on the macros which it finds. This is later used by the configure script (see above).
GNU-style projects, or not
Because automake tries to make a GNU-style project by default, it will add a COPYING file and complain if some other necessary informative text files are missing. You can add blank files with the following command:
touch NEWS README AUTHORS ChangeLogIf you do not want these GNU-style files, then you could add the following to your Makefile.am instead:
AUTOMAKE_OPTIONS = foreignThanks to Marc van Woerkom for this suggestion.
Telling automake about your source files
Use lines like the following to name your program and list its source files:
bin_PROGRAMS = hello hello_SOURCES = hello.h hello.cc main.ccNote that the second variable is prefixed with the value of the first variable. This is a common practice with autoconf and automake.
The Whole Process
Assuming that you have written appropriate Makefile.am and configure.ac files (there are examples below), you should be able to build your project by entering the following commands:
- 'autoheader' - creates config.h.in
- 'touch NEWS README AUTHORS ChangeLog'
- 'touch stamp-h'
- aclocal - adds aclocal.m4 to directory. Defines some m4 macros used by the auto tools.
- 'autoconf '- creates configure from configure.ac
- 'automake' - Creates Makefile.in from Makefile.am
- './configure' - creates Makefile from Makefile.in >
- 'make'
Just repeat the last 5 steps to completely rebuild the project. Most projects have an autogen.sh script that runs everything up to the configure step.
Project files should, of course, be organised in sub folders. Ideally, all of the source files should be in a folder called 'src' in the project folder, with all of the other files (such as makefiles, configure scripts, and readmes) separate at the top. Projects which have several levels of folders are called 'Deep' projects. I have listed the necessary steps here, but you should look at the Example Files section to see them in context.
When using sub-directories, you need to do the following:
1. Add a SUBDIRS entry to the top-level Makefile.am. For example:
SUBDIRS = doc intl po src testsNote that the directory names are separated only by spaces.
2. Add a Makefile.am file to every sub directory. The sub-directories do not need configure.ac files. Be sure to add the Makefiles to the list in the AC_OUPUT macro in the top-levelconfigure.ac.
For sub directories containing additional source code
3. Add the AC_PROG_RANLIB macro to your configure.ac. This will allow you to build code in sub-directories into temporary libraries, which make will then link in with the rest of the code.
4. Add some macros to the Makefile.am of any source directory under src. These will build a non-installing library. You need to give the library a name beginning with 'lib', specify the sources, and specify the locations of any header files. For example:
noinst_LIBRARIES = libfoo.a libfoo_a_SOURCES = foo.h foo.cc INCLUDES = -I@top_srcdir@/src/includesNotice that the SOURCES macro uses the library name with an underscore instead of a dot. Also, notice the use of the top_srcdir variable to refer to the top-level of the project.
5. Use a LDADD_ macro in the Makefile.am of a higher directory to link the temporary library with any code that uses it. For example,
LDADD = foofiles/libfoo.aFor sub directories containing non-source files
3. The Makefile.am in the sub-directory should contain a line like the following:
EXTRA_DIST = somefile.txt someotherfile.html
This tells automake that you want the files to be distributed, but that they do not need to be compiled.
Here are some example configure.ac and Makefile.am files. They are sufficient to manage a C++ project which uses the Standard Library.
See the automake and autoconf for information on the macros and variable names used in these files. I do not want to make this seem more complicated by explaining each line of these examples.
These examples are for a 'Deep' project with the following structure:
helloworld_cc configure.ac Makefile.am src Makefile.am helloworld.h helloworld.cc main.cc foofiles Makefile.am foo.h foo.cc
configure.ac
AC_INIT(src/hello.cc) AM_INIT_AUTOMAKE(hello,0.1) AM_CONFIG_HEADER(config.h) AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL AC_PROG_LIBTOOL AC_OUTPUT(Makefile src/Makefile src/foofiles/Makefile)Makefile.am
SUBDIRS = srcMakefile.am for the src directory
bin_PROGRAMS = hello hello_SOURCES = hello.h hello.cc main.cc SUBDIRS = foofiles LDADD = foofiles/libfoo.aMakefile.am for foofiles directory under src
noinst_LIBRARIES = libfoo.a libfoo_a_SOURCES = foo.h foo.cc INCLUDES = -I@top_srcdir@/You may download a simple example project here: helloworld_cc-0.3.tar.gz
I have found the following translations of this article;