BUILD SCRIPTS: how they work and how to modify them
===================================================

A guide to the Gutenprint build system.


Introduction
------------

Gutenprint uses GNU autoconf and automake to generate the scripts that
build the software.  It also uses libtool to create shared libraries.
This file describes how they work together.  It also discusses the
thinking behind how they are used in Gutenprint, and how to modify the
Gutenprint build scripts without breaking other things.  If you have
used autoconf and automake before, there will be little that is new in
this file, but you should note the conventions used in Gutenprint.

This file is split into the following sections:

        o Setting up the autotools
        o Integration of the autotools
        o Normal use of the tools
          - Using CVS
          - Setting up the build scripts from CVS
          - Building the package
        o configure.ac
          - Layout
          - AC_SUBST
          - AC_DEFINE and AC_DEFINE_UNQUOTED
          - AM_CONDITIONAL
        o Makefile.am
          - Automake basics
          - Make and subdirectories
          - Conditional compilation
          - When automake is not enough...
            + Rule syntax
            + Correctly referencing files
        o aclocal
        o config.h
        o libgutenprint
        o automake subtleties
        o libtool tricks
        o Testing changes to the build scripts
        o Further information
        o Known problems

I hope you find this useful. If any part was not clear, or there was
something that you would like covering, please let me know!

 -- Roger Leigh <rleigh@debian.org>



1. Setting up the autotools
---------------------------

To build Gutenprint from CVS, or to regenerate the build scripts after
modifying them, you need to install a number of GNU tools:

i.    GNU autoconf (at least 2.54; at least 2.59 recommended)
ii.   GNU automake (at least 1.9)
iii.  GNU libtool (at least 1.5; at least 1.5.20 recommended)
iv.   GNU gettext (at least 0.16)
v.    GNU make (any recent version)

and also

vi.   pkg-config (at least 0.18.0)

Additional packages are required to build certain parts of Gutenprint
from CVS that are not needed when building from a normal distribution.
These packages include:

vii.  flex/lex (for building the GIMP plugin and the test pattern generator)
viii. bison/yacc (for building the GIMP plugin and the test pattern generator)
ix.   doxygen (for building documentation)
x.    DocBook processors (db2html, db2pdf) (for building documentation)
xi.   DocBook-toys (called docbook-utils on some systems) (for building
      documentation)

These packages are in addition to the packages normally required to
build Gutenprint, as described in the README at top level.

If you are running a Debian-derived system (such as Ubuntu), installing
the following packages should prepare your environment for building
Gutenprint:

  autoconf
  autopoint
  byacc
  cvs
  docbook-utils
  doxygen
  flex
  gettext
  libglib2.0-dev
  libtool
  pkg-config
  sgmltools-lite
  texi2html


2. Integration of the autotools
-------------------------------

Each directory has a Makefile.am file which is processed by automake
to produce a Makefile.in.  In the root directory there is a
configure.ac.in which is processed by autoconf to make a script called
configure.  When run, configure does various tests and checks, and
then reads each Makefile.in to make a Makefile, and also generates a
header called config.h from config.h.in.  config.h.in is produced with
autoheader from configure.ac and acconfig.h.  autoconf also requires a
file aclocal.m4 which is generated by aclocal.

All these files are generated simply by running `./autogen.sh' in the
top directory.  If you are using a distributed version of Gutenprint,
as opposed to CVS, then they will already be present and the following
will not be necessary.

This is probably best demonstrated graphically.  The relationships
between the files are as follows:

During package setup (from CVS), running autogen.sh:

                                   autogen.sh
        m4extra/stp_release.m4.in ------------> m4/stp_release.m4

        gettext files added
        libtool files added
                                         aclocal
        m4/* + m4local/* + configure.ac ------------> aclocal.m4

                                         autoheader
              acconfig.h + configure.ac ------------> config.h.in

                                         automake
                            Makefile.am ------------> Makefile.in

                                         autoconf
              aclocal.m4 + configure.ac ------------> configure

Running configure:
                                         configure (->config.status)
                            Makefile.in ------------> Makefile
                            config.h.in ------------> config.h
                           headers.h.in ------------> headers.h
                           manpage.n.in ------------> manpage.n


3. Normal use of the tools
--------------------------

This section describes how to use the scripts for basic day-to-day
working.

3.1 Using CVS
-------------
The latest working copy of Gutenprint (HEAD) and all prior releases
are available from CVS either anonymously (read-only with CVS pserver)
or authenticated (read-write with SSH).  The modulename for Gutenprint
is 'print'.

Anonymous CVS access:
The module you wish to check out must be specified as the modulename.
When prompted for a password for anonymous, simply press the Enter
key.

        $ cvs -d:pserver:anonymous@gimp-print.cvs.sourceforge.net:/cvsroot/gimp-print login
        $ cvs -z3 -d:pserver:anonymous@gimp-print.cvs.sourceforge.net:/cvsroot/gimp-print co -P print

Developer CVS access via SSH:
Only project developers can access the CVS tree via this method.  SSH1
must be installed on your client machine.  Substitute modulename and
developername with the proper values.  Enter your site password when
prompted.  See the sourceforge documentation for more details,
including how to use RSA keys for authentication.

        $ export CVS_RSH=ssh
        $ cvs -z3 -d:ext:developername@gimp-print.cvs.sourceforge.net:/cvsroot/gimp-print co -P print

The CVS info documentation has very detailed explanations of
everything that can be done with CVS.

3.2 Setting up the build scripts from CVS
-----------------------------------------
After initially getting a copy of Gutenprint from CVS, or if any of
the scripts have changed, simply run autogen.sh:

        $ ./autogen.sh [options]

Note that one can pass any options to autogen.sh that one would
normally pass to configure.  './configure --help' will give a complete
list of options one can use.

3.3 Building the package
------------------------
The normal method for building from CVS is to run the `autogen.sh'
script, and then `make'.  The package can then be installed with 'make
install':

        $ ./autogen.sh [options]
        $ make
        $ make [DESTDIR=... VAR1=val1 VARn=valn] install

If the build scripts have been modified, it will not normally be
necessary to re-run autogen.sh: the Makefiles will notice and
regenerate themselves, running autoconf, automake, aclocal and
configure again if needed.

The build is only guaranteed to work if make is run from the top
level.  It should be possible to make individual subdirectories, but
sometimes this will cause problems e.g. if it depends on some other
directory that should have been built first.

A common problem is getting errors about a non-existent file called
`doc/version.texi'.  This file is automatically generated.  It will be
generated if you run make after running './autogen.sh' or './configure
--enable-maintainer-mode'.  It is only generated if `maintainer-mode'
is enabled, and should be present in the release tarball.

3.4 Extra make targets
----------------------
The Makefiles can do much more than build the package.  `targets' can
be given to make, which do various things.  They are used as follows:

        $ make target1 target2 ...

Some of the targets available are:

        all                     same as make with no targets
        clean                   remove everything generated by 'make all'
        distclean               as clean, and everything generated by configure
        maintainer-clean        as distclean, and everything generated by
                                autogen.sh
        install                 install the package
        uninstall               uninstall the package
        tags                    make tags tables
        dist                    make a distribution
        distcheck               as dist, but test it as well

Other targets are available. See Makefile for details.


4. configure.ac
---------------

This file is a Bourne shell script with m4 macros embedded in it.
autoconf expands the m4 macros to produce configure.  The configure
script includes macros from the m4 and m4local directories, including
ones to hard-code the release date into configure.

4.1 Layout
----------
The file is split into mostly discrete sections:

i.    Versioning details (including library versioning)
ii.   autoconf and automake initialisation
iii.  libtool setup
iv.   Default settings (now part of v)
v.    configure --with and --enable options
vi.   Checks for programs
vii.  Compiler flags
viii. Checks for libraries
ix.   Checks for headers
x.    Checks for typedefs, structures, and compiler characteristics
xi.   Define what has to be built (conditional compilation of things)
xii.  CUPS path settings
xiii. Definitions and substitutions
xiv.  Parse and output files

The ordering of sections is based solely on that some checks depend on
checks being performed previously.  There is sometimes some overlap
between sections, but any additions should go into the appropriate
section, if at all possible.  A new section may be created if there is
no suitable section.

4.2 AC_SUBST
------------
The main use of the configure script is to produce customised
Makefiles, and other files too.  This is done through the use of
AC_SUBST, which makes a variable get substituted in a file:

        ESCPUTIL_BIN="escputil"
        AC_SUBST(ESCPUTIL_BIN)

will replace any instance of @ESCPUTIL_BIN@ in a template file (ending
in .in'). E.g.

        bin_PROGRAMS = @ESCPUTIL_BIN@

4.3 AC_DEFINE and AC_DEFINE_UNQUOTED
------------------------------------
These macros are used to insert a #define in config.h.

        AC_DEFINE(MACRO)

will cause '#define MACRO 1' to appear in config.h (this will be of
the form '#undef MACRO' in config.h.in)

AC_DEFINE_UNQUOTED is the same as AC_DEFINE, except that a second
option can be used to define a string literal.

4.4 AM_CONDITIONAL
------------------
This is used to make certain parts of a Makefile conditional depending
on what happens in configure. It is used in the form:

        AM_CONDITIONAL(NAME, test)
        where name is the name of the conditional you define, and test
        is a check that must return true for the conditional to be
        defined.

This is used in a Makefile.am as follows:

        if NAME
        [do stuff]
        endif

Note that you cannot also use normal make conditionals.  Its main use
is to define macros, or to make a rule conditional.


5. Makefile.am
--------------

There is a Makefile.am in each directory, apart from a few where the
Makefile the next level up handles things.  Each Makefile.am is split
into several sections:

i.    Macros common to every Makefile.am
ii.   Path macros
iii.  Compiler macros
iv.   Build dependencies.  This is further split into a) binaries and b) data.
      Each of these sections has
      1. list of objects to build (if applicable)
      2. EXTRA_ objects (if applicable)
      3. Dependencies for each object (e.g. sources)
v.    Rules
vi.   Cleaning macros
vii.  EXTRA_DIST

Keeping everything in this logical order keeps them neat and readable.
Not every Makefile.am will have all these sections, but those that are
present should be ordered in this way.

5.1 Automake basics
-------------------
Automake parses Makefile.am, and generates rules in Makefile.in
depending on what it finds.  There are `primary' variables, such as
PROGRAMS, SCRIPTS, MANS, HEADERS and DATA that describe the type of
source one is defining.  These are coupled with a location to install
into.  For example, these are a few standard locations: bindir,
sbindir, mandir, datadir, pkgdatadir.  You can define your own quite
easily.  They are used together as follows:

        bin_PROGRAMS = myprog   [where bindir=$(prefix)/bin]
        pkgdata_DATA = datafile1 datafile2
                                [where pkgdatadir=$(prefix)/share/$(PACKAGE)]

Note! the 'dir' postfix is stripped off the location. I.e. bindir ->
bin.  That is all there is to it! You can use these simple variables
to describe everything in your source, and where is gets installed to.

In the case of PROGRAMS, one also has to specify the SOURCES as well.
E.g. in the example above, a binary called `myprog' was defined.  The
sources for this program are defined as follows:

        myprog_SOURCES = myprog.c myprog.h

automake will create all of the rules needed to build and install
everything.  An extra point is that suppose one doesn't want to
install something?  For this there is a 'noinst' macro, so that
noinst_PROGRAMS will not ever be installed.  One might also want
noinst_HEADERS. If one wanted to install headers, one would define

        includedir=$(prefix)/include
and then
        pkgincludedir=$(includedir)/$(PACKAGE).
Now
        pkginclude_HEADERS = myheader.h

will install the header into the correct location. Some of the
locations in the above examples are defined by default. The others
must be defined by hand.

There are also some macros with specific functions.  Any file that is
not mentioned in a macro, and also and MANS, will have to be put in an
EXTRA_DIST macro, so that automake knows to distribute them.

Also, some files might not be automatically cleaned. There are
CLEANFILES, DISTCLEANFILES and MAINTAINERCLEANFILES macros for use
with the 'clean', 'distclean' and 'maintainer-clean' make targets
respectively. Use with caution!  One does not want to clean things
that cannot be recreated!  CLEANFILES should be regenerated with
'make' as part of the build process, DISTCLEANFILES by configure
(e.g. Makefiles) and MAINTAINERCLEANFILES should be created by
'autogen.sh' and the programs it calls (e.g. Makefile.in's which are
created by automake).

5.2 Make and subdirectories
---------------------------
If a Makefile.am has a SUBDIRS macro, make will recurse through these
subdirectories, running make in each one.  e.g. in the top-level
Makefile.am:

        SUBDIRS = include src samples test po man doc scripts

In this case the order of directories is critical: lib, src and test
depend on include being built.  Also, test depends on libgutenprint in
src and po must be run after all the source has been built (as it
parses all C source, possibly including dynamically generated code).
The same applies in src/Makefile.am: most directories require
libgutenprint for linking with, and libgutenprint requires printdef.

Therefore the order of building is critical!  It should be technically
possible to run make in any subdirectory and have all the dependencies
satisfied by rules in that Makefile.  Unfortunately, this requires
complex rules in each directory, and this cannot be done as the source
tree gets bigger and more complex.  As a result, one should only run
make from the top level, as only this is certain to satisfy all
dependencies.

5.3 Conditional compilation
---------------------------
Most of the source is conditionally compiled according to the defaults
in configure.ac, which may be overridden by passing options to
configure, or possibly by the results of configure checks.  Depending
on the result, configure may substitute what to build into the
generated Makefile, e.g.:

        if BUILD_ESCPUTIL
        bin_PROGRAMS = escputil
        endif

If you use @@ substitutions, make sure that you use the EXTRA_ prefix
(e.g. EXTRA_PROGRAMS), so that automake knows what is to be built.

5.4 When automake is not enough...
----------------------------------
When one wants to do something that is not within the scope of the
facilities automake provides, one can write one's own rules, just like
in any other Makefile.

4.4.1 Rule syntax
Make rules take the following form:

        target ... : prerequisites ...
                commands
                ...
                ...
where
        target is the name of a file (or files) to create
        prerequisites are files that are needed to make the target
        commands are commands to make the target

The target will only be made if it does not exist or the timestamp on
any of the prerequisites is newer, indicating that it is out of date.

make is a complex program, and this is just the bare basic
operation. See the GNU make info documentation for a detailed
explanation.

4.4.2 Correctly referencing files
A file may be present either in the _source_ or _build_ directory,
which may or may not be the same.  The source directory contains the
unchanging source files, whereas the build directory contains all the
generated files, such as Makefiles, object code, libraries and
executables and also generated headers, C source and manual pages.
The macros to use are:

        $(srcdir)       The equivalent directory in the source tree
        .               The build directory (current directory)
        $(top_srcdir)   The highest level of the source tree
        $(top_builddir) The highest level of the build tree


6. aclocal
----------

aclocal contains all the macros that are needed by autoconf to
generate configure from configure.ac.  It is created by running
'aclocal'. If any of the macros are not present on your system, you
can point out where the macros distributed with Gutenprint are by
using '-I macrodir' with aclocal.


7. config.h
-----------

config.h is created by configure and should beincluded by all of the C
source files in the distribution.  It is created from config.h.in by
'configure'.  config.h.in is created from configure.ac by
'autoheader'.


8. libgutenprint
----------------

Any source that is to link with libgutenprint should include the gutenprint.h
header. The right way to do this is as follows:

        #include <gutenprint/gutenprint.h>

To ensure proper linking, the Makefile.am should have the following:

        program_LDADD = $(LIBGUTENPRINT_LIBS)

The Makefile.am should also include any necessary CFLAGS with:

        LOCAL_CPPFLAGS = $(LIBGUTENPRINT_CFLAGS)


9. automake subtleties
----------------------

Automake parses Makefile.am to produce Makefile.in.  Makefile.am looks
much like a normal Makefile, e.g. you can write your own rules in it.
However, it is not entirely like a normal Makefile.  In particular,
automake conditionals are not the same as make conditionals (which are
not available).

Another gotcha is that automake adds rules of its own, so you must make sure
that the names do not clash, or you may get obscure problems occurring
when you override an automake rule.


10. libtool tricks
------------------

libtool is used to create shared libraries.  One gotcha with libtool
is that if a program is linked with a libtool shared library in the
build tree, then it is actually created in '.libs/program', and not
'program'.  However, if it is statically linked (e.g. the platform
does not support shared libraries, or you used --disable-shared with
configure, perhaps to make the build faster or to be able to use
`valgrind' usefully), then it will be created as 'program'.  This is
so that you can run the program before you install it.  If it is
linked with shared libraries, a wrapper script does some magic with
LD_LIBRARY_PATH.  However, this means that your install rules must
take this into account by checking that '.libs/program exists', and
installing it if it is present, but otherwise installing 'program'.
Automake install rules do this automatically, but it you write your
own, you must take this into consideration.  The best option is to not
use custom install rules for binaries.


11. Testing changes to the build scripts
---------------------------------------

If you make a change to one of the scripts, simply running autogen.sh
and seeing if 'make' and 'make install' work is not enough.  In
particular, you must check that it does not break 'VPATH' builds where
the source and build directories are not the same.  To do this:

        $ mkdir /var/tmp/tmp-build
        $ cd /var/tmp/tmp-build
        $ ~roger/gutenprint/current/configure [options]
        $ make
        $ make DESTDIR=/var/tmp/tmp-inst install

You should also test that 'make install' works with and without
DESTDIR set.  Note that old gettext releases do not support DESTDIR,
but the current 0.10.x versions do.  The old gettext also breaks in
VPATH builds due to MKINSTALLDIRS being wrongly defined. This is also
fixed in the current version.


12. Further information
-----------------------

autoconf: autoconf.info
automake: automake.info
CVS:      cvs.info
gettext:  gettext.info
libtool:  libtool.info
make:     make.info



Local Variables:
mode: text
End:
