Using Autotools

by Robert Richter, 2005


Introduction

GNU Build System

see Autobook

Software portability and effective build systems are crucial aspects of modern software engineering practice. It is unlikely that a software project would be started today with the expectation that the software would run on only one platform. Autotools may help creating platform independent software packages and build systems, that make building software easier and less error prone are valuable.

Even if there is no need for creating platform independent software packages or adding Autotools to a project, Autotools are usefull to:

Common open source package installation process:

 $ ./configure
 $ make
 $ make install

Overview of Autotools

see info and help documentation

Tools available for package creation:

Aclocal

Generate 'aclocal.m4' by scanning 'configure.ac' or 'configure.in'. 'm4' is a powerful macro processor, in the sense that it copies its input to the output, expanding macros as it goes. This is needed by Autoconf for generating configure scripts.

Autoheader

Create a template file of C '#define' statements for 'configure' to use. To this end, scan TEMPLATE-FILE, or 'configure.ac' if present, or else 'configure.in'.

Libtool/Libtoolize

see Libtool manual

Libtool is a platform specific compiler/linker wrapper that provides a consistent interface for building software. Common modes are supported such as:

Since Libtool is platform dependent, Autoconf is used to generate a 'configure' script that determines platform specific settings and creates Libtool (see create Libtool with Autoconf).

The 'libtoolize' program provides a standard way to add libtool support to your package.

Automake

Automake is a tool for automatically generating 'Makefile.in's from files called 'Makefile.am'. Each 'Makefile.am' is basically a series of 'make' variable definitions, with rules being thrown in occasionally. The generated 'Makefile.in's are compliant with the GNU Makefile standards.

Autoconf

Generates a configuration script 'configure' from such as 'configure.ac' or 'configure.in'.

Autoscan

Examines source files in the project directory tree. Searchs the source files for common portability problems, checks for incompleteness of `configure.ac', and creates a file `configure.scan' which is a preliminary `configure.ac' for that package.

Autoreconf

Remake the GNU Build System files by scanning 'configure.ac' and running 'autoconf', 'autoheader', 'aclocal', 'automake' and 'libtoolize'.

Autoupdate

Updates 'configure.ac' to the syntax of the current version of Autoconf.

Ways to use Autotools

There are several ways to configure and build a project using Autotools. For each approach a set of various configuration files are needed:


Build libraries using Automake

see Autobook, Chapter 24.4.1, 24.4.2, 11

Automake provides the easiest way of setting up a GNU Build System. Files needed for setup are a standard configure.ac file with Automake macros and a makefile.am with some project specific make variable definitions. All remaining work such as the generation of Makefile templates and standard files needed for project build is processed by Automake. Since project setup depends on Automake tools, this approach is usefull for configuration of standard projects, but can not provide the flexibility resulting in special project needs such as the addition of special makefile rules.

 $ find
 .
 ./configure.ac
 ./hello.c
 ./hello.h
 ./main.c
 ./Makefile.am
 $ cat hello.c 
 #if HAVE_CONFIG_H
 #  include <config.h>
 #endif
 #include <stdio.h>
 #include "hello.h"
 int
 hello (const char *who)
 {
     printf("Hello, %s!\n", who);
     return 0;
 }
 $ cat hello.h 
 #ifndef HELLO_H
 #define HELLO_H 1
 extern int hello (const char *who);
 #endif /* !HELLO_H */
 $ cat main.c 
 #if HAVE_CONFIG_H
 #  include <config.h>
 #endif
 #include "hello.h"
 int
 main (int argc, const char *const argv[])
 {
     return hello("World");
 }
 $ cat configure.ac 
 # Process this file with autoconf to create configure.
 AC_INIT(hello.h)
 AM_CONFIG_HEADER(config.h:config.hin)
 AM_INIT_AUTOMAKE(hello, 1.0)
 AC_PROG_CC
 AM_PROG_CC_STDC
 AC_C_CONST
 AC_LIBTOOL_WIN32_DLL
 AM_PROG_LIBTOOL
 AC_OUTPUT(Makefile)
 $ cat Makefile.am 
 ## Process this file with automake to produce Makefile.in.
 lib_LTLIBRARIES         = libhello.la
 libhello_la_SOURCES     = hello.c
 libhello_la_LDFLAGS     = -no-undefined -avoid-version
 include_HEADERS         = hello.h
 bin_PROGRAMS            = hello
 hello_SOURCES           = main.c
 hello_LDADD             = libhello.la
 $ aclocal
 ...
 $ autoheader
 ...
 $ libtoolize --force --copy
 ...
 $ automake --add-missing --copy --foreign
 ...
 $ autoconf
 ...
 $ ./configure
 ...
 $ make
 ...
 $ make DESTDIR=`pwd`/inst/ install
 ...


Setup a basic Autoconf environment

Autoconf creates a 'configure' script from a 'configure.ac' file. See Autoconf manual, chapter 3.1.3 for the standard layout of Autoconf input files. An initial setup of configure.ac could be:

 $ cat configure.ac
 AC_INIT
 dnl configure Makefile creation from template file (Makefile.in):
 AC_CONFIG_FILES(Makefile)
 AC_OUTPUT

This example configure.ac file needs a template make file (Makefile.in) for the package, what can be derived from the projects Makefile. (For just setting up the environment it can be empty first.) With both files Autoconf can be run properly:

 $ touch Makefile.in
 $ ls
 Makefile.in  configure.in
 $ autoconf
 $ ./configure
 configure: creating ./config.status
 config.status: creating Makefile
 $ ls
 Makefile     autom4te.cache  config.status  configure.ac
 Makefile.in  config.log      configure


Build libraries using Autoconf and Autoscan

Autoscan provides an easy way to create a configure.ac file. Simply call Autoscan in your project and rename the configure.scan file to configure.ac. Also add appropriate build rules to your Makefile.in. Following example uses the same .h and .c files from the Automake example above:

 $ rm configure.ac
 $ ls
 Makefile.in  hello.c  hello.h  main.c
 $ cat Makefile.in 
 # Default goal - must be first rule
 all:
 # Project settings
 TARGETS = hello$(EXEEXT)
 hello-objs = libhello.la main.o
 libhello-objs = hello.lo
 PHONY_OBJS = hello-objs libhello-objs
 BIN_FILES = hello$(EXEEXT)
 LIB_FILES = libhello.la
 INC_FILES = hello.h
 # Project dependencies
 libhello-objs: $(libhello-objs)
 hello-objs: $(hello-objs)
 # Autoconf installation variables
 bindir = @bindir@
 exec_prefix = @exec_prefix@
 includedir = @includedir@
 libdir = @libdir@
 mkdir_p = @mkdir_p@
 prefix = @prefix@
 CFLAGS = @CFLAGS@
 EXEEXT = @EXEEXT@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 LDFLAGS = @LDFLAGS@
 SHELL = @SHELL@
 # Defined to prevent installation in root dir
 DESTDIR = $(CURDIR)/inst
 # General rules
 .PHONY: all \
         clean \
         realclean \
         install \
         uninstall \
         $(PHONY_OBJS)
 all:    $(TARGETS)
 clean:
         $(RM) *.la *.o *.lo *.dll *.a $(TARGETS)
 realclean: clean
         $(RM) -r .libs/ ./inst/
         find -name \*~ | xargs $(RM)
 INSTALL_BIN_FILES = $(addprefix $(DESTDIR)$(bindir)/, $(BIN_FILES))
 INSTALL_LIB_FILES = $(addprefix $(DESTDIR)$(libdir)/, $(LIB_FILES))
 INSTALL_INC_FILES = $(addprefix $(DESTDIR)$(includedir)/, $(INC_FILES))
 install: $(INSTALL_LIB_FILES) \
         $(INSTALL_BIN_FILES) \
         $(INSTALL_INC_FILES)
 uninstall:
         $(RM) $(patsubst $(DESTDIR)$(libdir)/lib%.la,$(DESTDIR)$(bindir)/cyg%.dll,$(INSTALL_LIB_FILES))
         $(RM) $(patsubst %.la,%.dll.a,$(INSTALL_LIB_FILES))
         $(RM) $(patsubst %.la,%.a,$(INSTALL_LIB_FILES))
         $(RM) $(INSTALL_BIN_FILES)
         $(RM) $(INSTALL_INC_FILES)
 $(INSTALL_BIN_FILES): $(DESTDIR)$(bindir)/%: %
         test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
         $(INSTALL) "$<" "$@"
 $(INSTALL_LIB_FILES): $(DESTDIR)$(libdir)/lib%.la: lib%.la
         test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
         $(INSTALL) "lib$*.dll.a" "$(DESTDIR)$(libdir)/lib$*.dll.a"
         $(INSTALL) "lib$*.a" "$(DESTDIR)$(libdir)/lib$*.a"
         test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
         $(INSTALL) "cyg$*.dll" "$(DESTDIR)$(bindir)/cyg$*.dll"
 $(INSTALL_INC_FILES): $(DESTDIR)$(includedir)/%: %
         test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
         $(INSTALL_DATA) "$<" "$@"
 # remake configuration automatically
 $(srcdir)/configure: configure.ac aclocal.m4
         cd $(srcdir) && autoconf
 # autoheader might not change config.h.in, so touch a stamp file.
 $(srcdir)/config.h.in: stamp-h.in
 $(srcdir)/stamp-h.in: configure.ac aclocal.m4
         cd $(srcdir) && autoheader
         echo timestamp > $(srcdir)/stamp-h.in
 config.h: stamp-h
 stamp-h: config.h.in config.status
         ./config.status
 Makefile: Makefile.in config.status
         ./config.status
 config.status: configure
         ./config.status --recheck
 # Build rules
 %.o:    %.c
         gcc -c $(CFLAGS) -o $@ $<
 %.lo:   %.c
         gcc -c $(CFLAGS) -o $*.o $<
         gcc -c $(CFLAGS) -DPIC -o $*.pic.o $<
         touch $@
 # The phony prerequisite here should be changed since this forces target build.
 lib%.la: lib%-objs
         gcc -shared $*.pic.o -o cyg$*.dll \
                 -Wl,--image-base=0x10000000 \
                 -Wl,--out-implib,lib$*.dll.a
         ar cru lib$*.a $*.o
         ranlib lib$*.a
         touch $@
 # The phony prerequisite here should be changed since this forces target build.
 %$(EXEEXT): %-objs
         gcc -g -O -o $@ $(filter %.o, $($*-objs)) \
                 $(patsubst %.la,%.dll.a,$(filter %.la, $($*-objs))) \
                 -Wl,--rpath -Wl,${libdir}
 $ touch configure.ac
 $ autoscan
 ...
 $ mv configure.scan configure.ac

Autoscan created a new configure.ac file with checks needed for C and configuration header file support:

 $ cat configure.ac 
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.59)
 AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
 AC_CONFIG_SRCDIR([hello.c])
 AC_CONFIG_HEADER([config.h])
 # Checks for programs.
 AC_PROG_CC
 AC_PROG_INSTALL
 AC_PROG_RANLIB
 # Checks for libraries.
 # Checks for header files.
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 # Checks for library functions.
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT

For creating config.h the autoheader tool is necessary. Also standard files such as install-sh that can be installed easily with Automake are needed. Follow these steps to finalize package generation:

 $ autoheader --force
 $ automake --add-missing --copy
 ...
 $ autoconf
 $ ls
 Makefile        autoscan.log  config.log     configure.ac  install-sh
 Makefile.in     config.h      config.status  hello.c       main.c
 autom4te.cache  config.h.in   configure      hello.h       missing


Add Libtool to your Autoconf project

Add Libtool handling to configure.ac and Makefile.in (see Libtool manual, chapter 5.3.1). Also add Automake initialisation to your configuration and generate a local Autoconf environment since Libtool requires Automake API for configuration.

Create a default configure.ac file by scanning with autoscan (see above). Add this to the appropriate sections of configure.ac:

 AM_INIT_AUTOMAKE(hello, 1.0)
 # Checks for programs.
 AC_PROG_LIBTOOL
 AC_SUBST(LIBTOOL_DEPS)

Add Libtool dependencies to Makefile.in and replace compiler and linker commands by Libtool wrapper commands:

 # Libtool dependencies
 LIBTOOL_DEPS = @LIBTOOL_DEPS@
 libtool: $(LIBTOOL_DEPS)
         $(SHELL) ./config.status --recheck

After changing the files, create the project environment, rescan it with Autoscan and modify configure.ac accordingly:

 $ ls
 Makefile.in  configure.ac  hello.c  hello.h  main.c
 $ aclocal
 ...
 $ autoheader --force
 $ automake --add-missing --copy
 ...
 $ libtoolize --copy
 ...
 $ autoscan

The resulting files look like these:

 $ cat configure.ac 
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.59)
 AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
 AM_INIT_AUTOMAKE(hello, 1.0)
 AC_CONFIG_SRCDIR([config.h.in])
 AC_CONFIG_HEADER([config.h])
 # Checks for programs.
 AC_PROG_CXX
 AC_PROG_CC
 AC_PROG_CPP
 AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
 AC_PROG_RANLIB
 AC_PROG_LIBTOOL
 AC_SUBST(LIBTOOL_DEPS)
 # Checks for libraries.
 # Checks for header files.
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 # Checks for library functions.
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
 $ cat Makefile.in 
 # Default goal - must be first rule
 all:
 # Project settings
 TARGETS = hello$(EXEEXT)
 hello-objs = libhello.la main.o
 libhello-objs = hello.lo
 PHONY_OBJS = hello-objs libhello-objs
 BIN_FILES = hello$(EXEEXT)
 LIB_FILES = libhello.la
 INC_FILES = hello.h
 # Project dependencies
 libhello-objs: $(libhello-objs)
 hello-objs: $(hello-objs)
 # Autoconf installation variables
 bindir = @bindir@
 exec_prefix = @exec_prefix@
 includedir = @includedir@
 libdir = @libdir@
 mkdir_p = @mkdir_p@
 prefix = @prefix@
 srcdir = @srcdir@
 CFLAGS = @CFLAGS@
 EXEEXT = @EXEEXT@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 LDFLAGS = @LDFLAGS@
 SHELL = @SHELL@
 # Defined to prevent installation in root dir
 DESTDIR = $(CURDIR)/inst
 # General rules
 .PHONY:        all \
        clean \
        realclean \
        $(PHONY_OBJS)
 all:   $(TARGETS)
 clean: libtool
        ./libtool --mode=clean $(RM) *.la *.o *.lo *.exe
 realclean: clean
        $(RM) stamp-h.in
        find -name \*~ | xargs $(RM)
 INSTALL_BIN_FILES = $(addprefix $(DESTDIR)$(bindir)/, $(BIN_FILES))
 INSTALL_LIB_FILES = $(addprefix $(DESTDIR)$(libdir)/, $(LIB_FILES))
 INSTALL_INC_FILES = $(addprefix $(DESTDIR)$(includedir)/, $(INC_FILES))
 # rpath needs to be specified in order to get shared libraries
 # (see Libtool Manual, 3.2 Linking libraries, Footnote 1)
 LDFLAGS += -rpath $(libdir) -no-undefined -avoid-version
 # Libtool dependencies
 LIBTOOL_DEPS = @LIBTOOL_DEPS@
 libtool: $(LIBTOOL_DEPS)
        $(SHELL) ./config.status --recheck
 # remake configuration automatically
 $(srcdir)/configure: configure.ac aclocal.m4
        cd $(srcdir) && autoconf
 # autoheader might not change config.h.in, so touch a stamp file.
 $(srcdir)/config.h.in: stamp-h.in
 $(srcdir)/stamp-h.in: configure.ac aclocal.m4
        cd $(srcdir) && autoheader
        echo timestamp > $(srcdir)/stamp-h.in
 config.h: stamp-h
 stamp-h: config.h.in config.status
        ./config.status
 Makefile: Makefile.in config.status
        ./config.status
 config.status: configure
        ./config.status --recheck
 # Install rules
 install: $(INSTALL_LIB_FILES) \
        $(INSTALL_BIN_FILES) \
        $(INSTALL_INC_FILES)
 uninstall:
        ./libtool --mode=clean $(RM) $(INSTALL_LIB_FILES)
        ./libtool --mode=clean $(RM) $(INSTALL_BIN_FILES)
        $(RM) $(INSTALL_INC_FILES)
 $(INSTALL_BIN_FILES): $(DESTDIR)$(bindir)/%: % libtool
        test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
        ./libtool --mode=install $(INSTALL) "$<" "$@"
 $(INSTALL_LIB_FILES): $(DESTDIR)$(libdir)/lib%.la: lib%.la
        test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
        test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
        ./libtool --mode=install $(INSTALL) "$<" "$@"
 $(INSTALL_INC_FILES): $(DESTDIR)$(includedir)/%: %
        test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
        $(INSTALL_DATA) "$<" "$@"
 # Build rules
 %.lo %.o: %.c libtool
        ./libtool --mode=compile gcc -g -c -O $(CFLAGS) -o $@ $<
 %.la:  %-objs libtool
        ./libtool --mode=link gcc -g -O $(LDFLAGS) -o $@ $($*-objs)
 %.exe: %-objs libtool
        ./libtool --mode=link gcc -g -O $(LDFLAGS) -o $@ $($*-objs)

Now the project is ready to build:

 $ aclocal
 ...
 $ autoheader --force
 $ automake --add-missing --copy; true;
 ...
 $ libtoolize --copy
 ...
 $ autoconf
 $ ./configure
 ...
 $ make
 ...
 $ make DESTDIR=`pwd`/inst install
 ...


Support build directories using Autoconf

see Autoconf Manual, chapter 4.7.3 Build Directories

Each Makefile.in should contain:

 srcdir = @srcdir@
 VPATH = @srcdir@

Due to VPATH limitations it might be necessary in certain cases to include the '$(srcdir)/' prefix in your Makefile.


Automatic remake configuration

see Autoconf, Chapter 4.7.4

Add this to Makefile.in:

 $(srcdir)/configure: configure.ac aclocal.m4
         cd $(srcdir) && autoconf
 # autoheader might not change config.h.in, so touch a stamp file.
 $(srcdir)/config.h.in: stamp-h.in
 $(srcdir)/stamp-h.in: configure.ac aclocal.m4
         cd $(srcdir) && autoheader
         echo timestamp > $(srcdir)/stamp-h.in
 config.h: stamp-h
 stamp-h: config.h.in config.status
         ./config.status
 Makefile: Makefile.in config.status
         ./config.status
 config.status: configure
         ./config.status --recheck

Add this to configure.ac:

 AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])

Add stamp-h.in to your package:

 $ touch stamp-h.in


Create Libtool with Autoconf for a specific platform

see manuals for Autoconf, Automake, Libtool see Autobook, Chapter 11.1

It is necessary to build Libtool for a specific platform with the use of Autoconf. That is Autoconf is required to create Libtool and basic knowledge about generating Autoconf input files (e.g. configure.ac) is essential. Autoconf generates a 'configure' script that creates Libtool. Once Libtool is available for a platform, it can be used for various software builds and packages without recreation. Follow these steps to create Libtool:

Create this configure.ac file:

 $ cat configure.ac
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.59)
 AC_INIT
 # Checks for programs.
 AC_PROG_LIBTOOL
 AC_SUBST(LIBTOOL_DEPS)
 # Checks for libraries.
 # Checks for header files.
 # Checks for typedefs, structures, and compiler characteristics.
 # Checks for library functions.
 AC_OUTPUT

Now run Autoconf:

 $ ls
 configure.ac
 $ aclocal
 ...
 $ automake --add-missing --copy
 ...
 $ libtoolize --copy
 ...
 $ autoconf
 ...
 $ ls -t
 ltmain.sh   config.guess  install-sh      configure   configure.ac
 config.sub  missing       autom4te.cache  aclocal.m4
 $ ./configure
 ...
 $ ls -t
 config.log     ltmain.sh     missing         configure
 config.status  config.sub    install-sh      aclocal.m4
 libtool        config.guess  autom4te.cache  configure.ac

The run produced in the end a ./libtool shell script generated by Autoconf for usage in Makefiles on the target platform.


Build libraries using only Libtool

Copy libtool to your project. See 'How to create Libtool with Autoconf for a specific platform' for creating the file. Also add a Makefile as shown to the project containing all necessary libtool build and install rules for the project. Then run make:

 $ ls   
 Makefile  hello.c  hello.h  libtool  main.c
 $ cat Makefile
 # Autoconf installation variables
 bindir = ${exec_prefix}/bin
 exec_prefix = ${prefix}
 includedir = ${prefix}/include
 libdir = ${exec_prefix}/lib
 mkdir_p = mkdir -p --
 prefix = /usr/local
 top_builddir = .
 EXEEXT = .exe
 INSTALL = /usr/bin/install -c
 INSTALL_DATA = ${INSTALL} -m 644
 SHELL = /bin/bash
 # Defined to prevent installation in root dir
 DESTDIR = $(CURDIR)/inst
 # Libtool
 LIBTOOL = $(SHELL) $(top_builddir)/libtool
 # Default goal - must be first rule
 all:
 # Project settings
 TARGETS = hello$(EXEEXT)
 hello-objs = libhello.la main.o
 libhello-objs = hello.lo
 PHONY_OBJS = hello-objs libhello-objs
 BIN_FILES = hello$(EXEEXT)
 LIB_FILES = libhello.la
 INC_FILES = hello.h
 libhello-objs: $(libhello-objs)
 hello-objs: $(hello-objs)
 # General rules
 .PHONY: all \
         clean \
         realclean \
         install \
         uninstall \
         $(PHONY_OBJS)
 all:    $(TARGETS)
 clean:
         $(LIBTOOL) --mode=clean $(RM) *.la *.o *.lo $(TARGETS)
 realclean: clean
         $(RM) -r .libs/ ./inst/
         find -name \*~ | xargs $(RM)
 INSTALL_BIN_FILES = $(addprefix $(DESTDIR)$(bindir)/, $(BIN_FILES))
 INSTALL_LIB_FILES = $(addprefix $(DESTDIR)$(libdir)/, $(LIB_FILES))
 INSTALL_INC_FILES = $(addprefix $(DESTDIR)$(includedir)/, $(INC_FILES))
 install: $(INSTALL_LIB_FILES) \
         $(INSTALL_BIN_FILES) \
         $(INSTALL_INC_FILES)
 uninstall:
         $(LIBTOOL) --mode=uninstall $(RM) $(INSTALL_LIB_FILES)
         $(LIBTOOL) --mode=uninstall $(RM) $(INSTALL_BIN_FILES)
         $(RM) $(INSTALL_INC_FILES)
 $(INSTALL_BIN_FILES): $(DESTDIR)$(bindir)/%: %
         test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
         $(LIBTOOL) --mode=install $(INSTALL) "$<" "$@"
 $(INSTALL_LIB_FILES): $(DESTDIR)$(libdir)/%: %
         test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
         $(LIBTOOL) --mode=install $(INSTALL) "$<" "$@"
 $(INSTALL_INC_FILES): $(DESTDIR)$(includedir)/%: %
         test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
         $(INSTALL_DATA) "$<" "$@"
 # rpath needs to be specified in order to get shared libraries
 # (see Libtool Manual, 3.2 Linking libraries, Footnote 1)
 LDFLAGS += -rpath $(libdir) -no-undefined -avoid-version
 # Build rules
 %.lo %.o: %.c
         $(LIBTOOL) --mode=compile gcc -g -c -O $(CFLAGS) -o $@ $<
 %.la:   %-objs
         $(LIBTOOL) --mode=link gcc -g -O $(LDFLAGS) -o $@ $($*-objs)
 %$(EXEEXT): %-objs
         $(LIBTOOL) --mode=link gcc -g -O $(LDFLAGS) -o $@ $($*-objs)
 $ make
 ...
 $ make DESTDIR=`pwd`/inst install
 ...
 $ find inst -type f
 inst/usr/local/bin/cyghello.dll
 inst/usr/local/bin/hello.exe
 inst/usr/local/include/hello.h
 inst/usr/local/lib/libhello.a
 inst/usr/local/lib/libhello.dll.a
 inst/usr/local/lib/libhello.la