automake: CVS
1
1 27.1 CVS and generated files
1 ============================
1
1 Background: distributed generated Files
1 ---------------------------------------
1
1 Packages made with Autoconf and Automake ship with some generated files
1 like ‘configure’ or ‘Makefile.in’. These files were generated on the
1 developer’s machine and are distributed so that end-users do not have to
1 install the maintainer tools required to rebuild them. Other generated
1 files like Lex scanners, Yacc parsers, or Info documentation, are
1 usually distributed on similar grounds.
1
1 Automake output rules in ‘Makefile’s to rebuild these files. For
1 instance, ‘make’ will run ‘autoconf’ to rebuild ‘configure’ whenever
1 ‘configure.ac’ is changed. This makes development safer by ensuring a
1 ‘configure’ is never out-of-date with respect to ‘configure.ac’.
1
1 As generated files shipped in packages are up-to-date, and because
1 ‘tar’ preserves times-tamps, these rebuild rules are not triggered when
1 a user unpacks and builds a package.
1
1 Background: CVS and Timestamps
1 ------------------------------
1
1 Unless you use CVS keywords (in which case files must be updated at
1 commit time), CVS preserves timestamp during ‘cvs commit’ and ‘cvs
1 import -d’ operations.
1
1 When you check out a file using ‘cvs checkout’ its timestamp is set
1 to that of the revision that is being checked out.
1
1 However, during ‘cvs update’, files will have the date of the update,
1 not the original timestamp of this revision. This is meant to make sure
1 that ‘make’ notices sources files have been updated.
1
1 This timestamp shift is troublesome when both sources and generated
1 files are kept under CVS. Because CVS processes files in lexical order,
1 ‘configure.ac’ will appear newer than ‘configure’ after a ‘cvs update’
1 that updates both files, even if ‘configure’ was newer than
1 ‘configure.ac’ when it was checked in. Calling ‘make’ will then trigger
1 a spurious rebuild of ‘configure’.
1
1 Living with CVS in Autoconfiscated Projects
1 -------------------------------------------
1
1 There are basically two clans amongst maintainers: those who keep all
1 distributed files under CVS, including generated files, and those who
1 keep generated files _out_ of CVS.
1
1 All Files in CVS
1 ................
1
1 • The CVS repository contains all distributed files so you know
1 exactly what is distributed, and you can checkout any prior version
1 entirely.
1
1 • Maintainers can see how generated files evolve (for instance, you
1 can see what happens to your ‘Makefile.in’s when you upgrade
1 Automake and make sure they look OK).
1
1 • Users do not need the autotools to build a checkout of the project,
1 it works just like a released tarball.
1
1 • If users use ‘cvs update’ to update their copy, instead of ‘cvs
1 checkout’ to fetch a fresh one, timestamps will be inaccurate.
1 Some rebuild rules will be triggered and attempt to run developer
1 tools such as ‘autoconf’ or ‘automake’.
1
1 Calls to such tools are all wrapped into a call to the ‘missing’
1 script discussed later (⇒maintainer-mode), so that the user
1 will see more descriptive warnings about missing or out-of-date
1 tools, and possible suggestions about how to obtain them, rather
1 than just some “command not found” error, or (worse) some obscure
1 message from some older version of the required tool they happen to
1 have installed.
1
1 Maintainers interested in keeping their package buildable from a
1 CVS checkout even for those users that lack maintainer-specific
1 tools might want to provide an helper script (or to enhance their
1 existing bootstrap script) to fix the timestamps after a ‘cvs
1 update’ or a ‘git checkout’, to prevent spurious rebuilds. In case
1 of a project committing the Autotools-generated files, as well as
1 the generated ‘.info’ files, such script might look something like
1 this:
1
1 #!/bin/sh
1 # fix-timestamp.sh: prevents useless rebuilds after "cvs update"
1 sleep 1
1 # aclocal-generated aclocal.m4 depends on locally-installed
1 # '.m4' macro files, as well as on 'configure.ac'
1 touch aclocal.m4
1 sleep 1
1 # autoconf-generated configure depends on aclocal.m4 and on
1 # configure.ac
1 touch configure
1 # so does autoheader-generated config.h.in
1 touch config.h.in
1 # and all the automake-generated Makefile.in files
1 touch `find . -name Makefile.in -print`
1 # finally, the makeinfo-generated '.info' files depend on the
1 # corresponding '.texi' files
1 touch doc/*.info
1
1 • In distributed development, developers are likely to have different
1 version of the maintainer tools installed. In this case rebuilds
1 triggered by timestamp lossage will lead to spurious changes to
1 generated files. There are several solutions to this:
1
1 • All developers should use the same versions, so that the
1 rebuilt files are identical to files in CVS. (This starts to
1 be difficult when each project you work on uses different
1 versions.)
1 • Or people use a script to fix the timestamp after a checkout
1 (the GCC folks have such a script).
1 • Or ‘configure.ac’ uses ‘AM_MAINTAINER_MODE’, which will
1 disable all of these rebuild rules by default. This is
1 further discussed in ⇒maintainer-mode.
1
1 • Although we focused on spurious rebuilds, the converse can also
1 happen. CVS’s timestamp handling can also let you think an
1 out-of-date file is up-to-date.
1
1 For instance, suppose a developer has modified ‘Makefile.am’ and
1 has rebuilt ‘Makefile.in’, and then decides to do a last-minute
1 change to ‘Makefile.am’ right before checking in both files
1 (without rebuilding ‘Makefile.in’ to account for the change).
1
1 This last change to ‘Makefile.am’ makes the copy of ‘Makefile.in’
1 out-of-date. Since CVS processes files alphabetically, when
1 another developer ‘cvs update’s his or her tree, ‘Makefile.in’ will
1 happen to be newer than ‘Makefile.am’. This other developer will
1 not see that ‘Makefile.in’ is out-of-date.
1
1 Generated Files out of CVS
1 ..........................
1
1 One way to get CVS and ‘make’ working peacefully is to never store
1 generated files in CVS, i.e., do not CVS-control files that are
1 ‘Makefile’ targets (also called _derived_ files).
1
1 This way developers are not annoyed by changes to generated files.
1 It does not matter if they all have different versions (assuming they
1 are compatible, of course). And finally, timestamps are not lost,
1 changes to sources files can’t be missed as in the
1 ‘Makefile.am’/‘Makefile.in’ example discussed earlier.
1
1 The drawback is that the CVS repository is not an exact copy of what
1 is distributed and that users now need to install various development
1 tools (maybe even specific versions) before they can build a checkout.
1 But, after all, CVS’s job is versioning, not distribution.
1
1 Allowing developers to use different versions of their tools can also
1 hide bugs during distributed development. Indeed, developers will be
1 using (hence testing) their own generated files, instead of the
1 generated files that will be released actually. The developer who
1 prepares the tarball might be using a version of the tool that produces
1 bogus output (for instance a non-portable C file), something other
1 developers could have noticed if they weren’t using their own versions
1 of this tool.
1
1 Third-party Files
1 -----------------
1
1 Another class of files not discussed here (because they do not cause
1 timestamp issues) are files that are shipped with a package, but
1 maintained elsewhere. For instance, tools like ‘gettextize’ and
1 ‘autopoint’ (from Gettext) or ‘libtoolize’ (from Libtool), will install
1 or update files in your package.
1
1 These files, whether they are kept under CVS or not, raise similar
1 concerns about version mismatch between developers’ tools. The Gettext
11 manual has a section about this, see ⇒CVS Issues (gettext)CVS
Issues.
1