Next: , Previous: , Up: Building Programs and Libraries   [Contents][Index]


9.1 Building a program

9.1.1 Introductory blathering

In a directory containing source that gets built into a program (as opposed to a library or a script), the ‘PROGRAMS’ primary is used. Programs can be installed in bindir, sbindir, libexecdir, pkglibdir, or not at all (‘noinst’). They can also be built only for make check, in which case the prefix is ‘check’.

For instance:

bin_PROGRAMS = hello

In this simple case, the resulting Makefile.in will contain code to generate a program named hello.

Associated with each program are several assisting variables which are named after the program. These variables are all optional, and have reasonable defaults. Each variable, its use, and default is spelled out below; we use the “hello” example throughout.

The variable hello_SOURCES is used to specify which source files get built into an executable:

hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h

This causes each mentioned ‘.c’ file to be compiled into the corresponding ‘.o’. Then all are linked to produce hello.

If ‘hello_SOURCES’ is not specified, then it defaults to the single file hello.c; that is, the default is to compile a single C file whose base name is the name of the program itself. (This is a terrible default but we are stuck with it for historical reasons.)

Multiple programs can be built in a single directory. Multiple programs can share a single source file, which must be listed in each ‘_SOURCES’ definition.

Header files listed in a ‘_SOURCES’ definition will be included in the distribution but otherwise ignored. In case it isn’t obvious, you should not include the header file generated by configure in a ‘_SOURCES’ variable; this file should not be distributed. Lex (‘.l’) and Yacc (‘.y’) files can also be listed; see Yacc and Lex support.

9.1.2 Conditional compilations

You can’t put a configure substitution (e.g., ‘@FOO@’) into a ‘_SOURCES’ variable. The reason for this is a bit hard to explain, but suffice to say that it simply won’t work. Automake will give an error if you try to do this.

Automake must know all the source files that could possibly go into a program, even if not all the files are built in every circumstance. Any files which are only conditionally built should be listed in the appropriate ‘EXTRA_’ variable. For instance, if hello-linux.c were conditionally included in hello, the Makefile.am would contain:

EXTRA_hello_SOURCES = hello-linux.c

In this case, hello-linux.o would be added, via a configure substitution, to hello_LDADD in order to cause it to be built and linked in.

An often simpler way to compile source files conditionally is to use Automake conditionals. For instance, you could use this construct to conditionally use hello-linux.c or hello-generic.c as the basis for your program hello:

if LINUX
hello_SOURCES = hello-linux.c
else
hello_SOURCES = hello-generic.c
endif

When using conditionals like this you don’t need to use the ‘EXTRA_’ variable, because Automake will examine the contents of each variable to construct the complete list of source files.

Sometimes it is useful to determine the programs that are to be built at configure time. For instance, GNU cpio only builds mt and rmt under special circumstances.

In this case, you must notify Automake of all the programs that can possibly be built, but at the same time cause the generated Makefile.in to use the programs specified by configure. This is done by having configure substitute values into each ‘_PROGRAMS’ definition, while listing all optionally built programs in EXTRA_PROGRAMS.

Of course you can use Automake conditionals to determine the programs to be built.

9.1.3 Linking the program

If you need to link against libraries that are not found by configure, you can use LDADD to do so. This variable is used to specify additional objects or libraries to link with; it is inappropriate for specifying specific linker flags, you should use AM_LDFLAGS for this purpose.

Sometimes, multiple programs are built in one directory but do not share the same link-time requirements. In this case, you can use the ‘prog_LDADD’ variable (where prog is the name of the program as it appears in some ‘_PROGRAMS’ variable, and usually written in lowercase) to override the global LDADD. If this variable exists for a given program, then that program is not linked using LDADD.

For instance, in GNU cpio, pax, cpio and mt are linked against the library libcpio.a. However, rmt is built in the same directory, and has no such link requirement. Also, mt and rmt are only built on certain architectures. Here is what cpio’s src/Makefile.am looks like (abridged):

bin_PROGRAMS = cpio pax @MT@
libexec_PROGRAMS = @RMT@
EXTRA_PROGRAMS = mt rmt

LDADD = ../lib/libcpio.a @INTLLIBS@
rmt_LDADD =

cpio_SOURCES = …
pax_SOURCES = …
mt_SOURCES = …
rmt_SOURCES = …

prog_LDADD’ is inappropriate for passing program-specific linker flags (except for ‘-l’, ‘-L’, ‘-dlopen’ and ‘-dlpreopen’). So, use the ‘prog_LDFLAGS’ variable for this purpose.

It is also occasionally useful to have a program depend on some other target which is not actually part of that program. This can be done using the ‘prog_DEPENDENCIES’ variable. Each program depends on the contents of such a variable, but no further interpretation is done.

If ‘prog_DEPENDENCIES’ is not supplied, it is computed by Automake. The automatically-assigned value is the contents of ‘prog_LDADD’, with most configure substitutions, ‘-l’, ‘-L’, ‘-dlopen’ and ‘-dlpreopen’ options removed. The configure substitutions that are left in are only ‘@LIBOBJS@’ and ‘@ALLOCA@’; these are left because it is known that they will not cause an invalid value for ‘prog_DEPENDENCIES’ to be generated.


Next: Building a library, Previous: Building Programs and Libraries, Up: Building Programs and Libraries   [Contents][Index]