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 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 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: