Simple guide for Automake/Autoconf by Nick

 

Simple guide for Automake/Autoconf

Abstract

Automake and Autoconf are great projects and tools in GNU. This paper can’t describe all but main steps. It will explian Automake and Autoconf in short but clear sentences.

Introduce

Everyone who use Linux and Unix to program, knows that what is Makefile. However, if you do a big project, I think the Makefile is tedious and boring. Now, we can use Automake and Autoconf to generate Makefiles instead of editing them by ourselves.

The Automake and Autoconf are GNU project and someone must know these 3 steps: configure / make / make install. It’s simple and easy but the process is not simple. This article will teach you how to use Automake and Autoconf.

How to Automake and Autoconf

We see a lot of tools in Automake and Autoconf. In fact, there are only 2 parts:

I.             Call every tools in sequence.

II.          Modify or add three files.

 

Now, let’s see the steps in detail.

1.      Call autoscan in the project folder. It will generate configure.scan. Then we need to rewrite its name to configure.ac.

$ autoscan

$ mv configure.scan configure.ac

 

2.      Modify configure.ac, Autoconf offers all kinds of M4 macro which project need them to detect some configure items.

3.      Call aclocal to collect non-autoconf macro (self-define macro) in configure.ac.

$ aclocal

 

4.      Call autoheader. It will sacan configure.ac, acconfig.h and gnerate config.h.in file. This file describes some special macro(such as AD_DEFINE) according to configure.ac.

$ autoheader

 

5.      Edit Makefile.am according to rules of Automake. Makefile.am mainly describes objects of compiling and source code files.

6.      Call Automake. It will generate Makefile.in and a series files by Makefile.am. (Note: You can use “-a” to generate these lack of files. But you still need to create some files using “touch” command: touch NEWS, README AUTHORS ChangeLog) If configure.ac uses libtool(AC_PROG_LIBTOOL(old version) or LI_INIT), you should excute “libtoolize –automake –copy --force” on the root directory of project to generate ltmain.sh which Automake and config.status will call.

$ automake –a

$ touch NEWS README AUTHORS ChangLog

 

7.      Call autoconf. It will generate shell script configure according to configure.ac.

$ autoconf

8.      Call configure to obtain Makefile. Then you can make and make install.

$ ./configure

$ make

$ make install

 

Above steps, there are 8 steps but 5 steps you can type them and press “ENTER” bottom. The other 3 steps shoud edit and modify something by yourselves. Let’s talk about how to do in next.

 

I.  Modify configure.ac

Every configure.ac should have lines like the following:

AC_INIT([Hello], [VERSION], [BUG-REPORT-ADDRESS])

AC_PREREQ([2.59])

AM_INIT_AUTOMAKE([1.10 no-define])

AC_CONFIG_HEADERS([config.h])

AC_PROG_CXX

AC_CONFIG_FILES([Makefile src/Makefile src/lib/Makefile common/Makefile])

AC_OUTPUT

The AC_INIT macro initializes autoconf with information about your project, including the project name, version number, bug-reporting address, tarball name and the project homepage.

The AM_INIT_AUTOMAKE line adds several standard checks and initializes automake.

AC_PROG_CXX checks for a C++ compiler. If your project uses C, you can check for a C compiler with AC_PROG_CC.

AC_CONFIG_FILES lists the files to be generated by configure. By default, each file is generated from a template file of the same name but with an .in extension appended.

AC_OUTPUT finishes configure processing, and generates the output files.

 

II. Edit self-define Autoconf macro

       In some circustance, although there are a lot of macro defined by Autoconf, we also want to define some macros by ourselves.

       Create a new folder named m4. I prefer every macro a file. The name of file is macro’s name.

       The edition method refer to Autoconf guide. I can’t write everything here.

       Call aclocal to generate aclocal.m4 : $ aclocal –l m4

At the same time, you should add ACLOCAL_AMFLAGS = -l m4. on Makefile.am in the project’ directory.

 

III. Edit Makefile.am

Automake creates complex Makefile.ins from simple Makefile.ams.

Makefile.ams follow roughly the same syntax as Makefiles however they usually contains only variable definitions.

 

       where_PRIMARY Convention for Declaring Targets

where_PRIMARY = targets ...

targets should be built as...

_PROGRAMS

_LIBRARIES

_LTLIBRARIES(Libtool libraries)

_HEADERS

_SCRIPTS

_DATA

 

targets should be installed in...

bin_ $(bindir)

lib_ $(libdir)

….

custom_  $(customdir )

 

               You define customdir.

noinst_         Not installed.

 

check_   Built by ‘make check’.

 

Optionally:

     dist_ Distribute targets (if not the default)

     nodist Don’t distribute targets.

 

 

Standard File System Hierarchy

Directory variable

Default value

prefix

/usr/ local

exec-prefix

prex

bindir

exec-prefix /bin

libdir

exec-prefix/lib

Includedir

prefix/include

datarootdir

prefix/share

datadir

datarootdir

mandir

datarootdir/man

infodir

datarootdir/info

 

Declaring Sources

 

Makefile.am

bin_PROGRAMS = foo run-me

 

foo_SOURCES = foo.c foo.h print.c print.h

 

run_me_SOURCES = run.c run.h print.c

 

 

These programs will be installed in $(bindir).

 

The sources of each program go into program SOURCES.

 

Non-alphanumeric characters are mapped to ‘_ ’.

 

Automake automatically computes the list of objects to build and link from these files.

 

Header files are not compiled.

We list them only so they get distributed (Automake does not distribute files it does not know about).

It’s OK to use the same source for two programs.

Compiler and linker are inferred from the extensions.

 

 

 

(Static) Libraries

Add AC PROG RANLIB to configure.ac.

 

 

Makefile.am

 

lib_LIBRARIES = libfoo.a libbar.a

 

libfoo_a_SOURCES = foo.c privfoo.h

 

libbar_a_SOURCES = bar.c privbar.h

 

include_HEADERS = foo.h bar.h

 

 

These libraries will be installed in $(libdir).

 

Library names must match lib*.a.

 

Public headers will be installed in $(includedir).

 

Private headers are not installed, like ordinary source files.

 

You may have one Makefile (hence one Makefile.am) per directory.

 

 

 

They must all be declared in configure.ac.

 

configure.ac

 

AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile

 

src/dira/Makefile src/dirb/Makefile])

 

 

 

‘make’ is run at the top-level.

 

Makefile.ams should fix the order in which to recurse directories using

 the SUBDIRS variable.

 

Makefile.am

 

src/ Makefile.am

 

SUBDIRS = lib src

 

SUBDIRS = dira dirb .

 

The current directory is implicitly built after subdirectories.

 

You can put ‘.’ where you want to override this.

 

 

Remember VPATH builds: a source file is not necessary in the current directory.

 

There are two twin trees: the build tree, and the source tree.

 

       Makefile and objects files are in the build tree.

 

       Makefile.in, Makefile.am, and source files are in the source tree.

 

       If ‘./configure’ is run in the current directory, the two trees are one.

 

In each Makefile, ‘config.status’ will define $(srcdir): the path to the matching source directory.

 

When referring to sources files or targets in Automake variables, you do not have to worry about source vs. build, because ‘make’ will check both directories.

 

You may need $(srcdir) when specifying flags for tools, or writing custom commands. E.g., to tell the compiler to include headers from dir/ , you should write -I$(srcdir)/dir, not -Idir. (-Idir would fetch headers from the build tree.)

 

 

lib/ Makefile.am

 

noinst_LIBRARIES = libcompat.a

 

libcompat_a_SOURCES = xalloc.c xalloc.h

 

This is a convenience library, used only when building the package.

 

src/ Makefile.am

 

bin_PROGRAMS = foo run-me

 

foo_SOURCES = foo.c foo.h print.c print.h

 

run_me_SOURCES = run.c run.h print.c

 

run_me_LDADD = ../lib/libcompat.a

 

run_me_CPPFLAGS = -I$(srcdir)/../lib

 

LDADD is added when linking all programs.

 

AM CPPFLAGS contains additional preprocessor flags.

 

You can use per-target variables: they apply to a single program.

 

 

Per-Target Flags

 

Assuming foo is a program or library:

 

foo CFLAGS Additional C compiler flags

 

foo CPPFLAGS Additional preprocessor flags (-Is and -Ds)

 

foo LDADD Additional link objects, -ls and -Ls (if foo is a program)

 

foo LIBADD Additional link objects, -ls and -Ls (if foo is a library)

 

foo LDFLAGS Additional linker flags

 

The default value for foo XXXFLAGS is $(AM XXXFLAGS).

 

Use plain file names to refer to libraries inside your package (keep -ls and

 

-Ls for external libraries only).

 

 

src/ Makefile.am

 

bin_PROGRAMS = foo run-me

 

foo_SOURCES = foo.c foo.h print.c print.h

 

run_me_SOURCES = run.c run.h print.c

 

run_me_CPPFLAGS = -I$(srcdir)/../lib

 

run_me_LDADD = ../lib/libcompat.a

 

  

 

The Ultimate Summary

 

1) Create sources, “Makefile.am”

 

2) `autoscan`

 

3) Rename “configure.scan” to “configure.ac”

 

4) `autoheader`

 

5) Add AM_INIT_AUTOMAKE to “configure.ac”

 

6) `aclocal`

 

7) `automake --add-missing --copy`

 

8) `autoconf`

 

9) `./configure`

 

10) `make`

 

11)    `make install`

 

                                                                                    Reporter: Nick Chan

                                                                                    2012.8.29

posted @ 2012-08-30 16:19  Rabbit Nick  阅读(253)  评论(0编辑  收藏  举报