Subversion uses a different approach. On the up side, Subversion uses a repository version number to address a particular combination of file revisions at a certain point in time. This is perfect from a developers point of view, but it comes at a price: Subversion cannot do string replacements as CVS does, because a single revision of a file can be part of several revisions of the repository. The Subversion FAQ suggests to use the tool "svnversion" to generate a definition for C files or to generate a small C file containing the version number. I tried to integrate the Subversion revision into the RefDB binaries lately, but it turned out to be far more complicated than the FAQ suggested.
Using svnversion in a Makefile is straightforward, but what happens if you package the project and try to build it on a different box? If Subversion is installed, svnversion will return "exported" instead of a revision number, as it needs the housekeeping files of a Subversion working copy in order to return the revision number. This is not what we want. What happens if you try to build the project on a box that does not have Subversion installed at all? Right, the build fails. That is, the FAQ suggestion will work only for users that build straight from a Subversion working copy.
In order to get useful version informations from builds outside of a Subversion working copy, we need to record the version when the distribution was built, and use that instead of the information returned by svnversion. This needs a little preparation in configure.in:
--8<----
dnl see whether subversion is installed
AC_PATH_PROG(svnversioncommand, svnversion)
dnl use svnversion to record the current repository revision only if
dnl subversion is installed and we are in a working copy
if test "X$svnversioncommand" = "X" || test `$svnversioncommand -n '.'` = "exported"; then
mysvnversion="cat svn_dist_version"
else
mysvnversion="svnversion -n '.'"
fi
AM_CONDITIONAL(HAVESVNWC, test "X$svnversioncommand" != "X" && test `$svnversioncommand -n '.'` != "exported")
AC_SUBST(mysvnversion)
--8<----
Now we have a variable $mysvnversion which contains a command that emits a revision number. This is either set to a call to svnversion (for working copies) or to a cat command which uses a previously generated version number (we'll see how this is generated shortly).
The remaining stuff goes into src/Makefile.am. First, we follow the Subversion FAQ suggestions almost literally:
--8<----
svn_version.c: FORCE
echo -n 'const char* svn_version(void) { const char* SVN_Version = "' > svn_version.c
@mysvnversion@ >> svn_version.c
echo '"; return SVN_Version; }' >> svn_version.c
FORCE:
--8<----
The only change is that we don't call svnversion directly, but use the substituted value of $mysvnversion from configure.in. The result is a short source file which is generated whenever we run "make all" and which we can include into the
--8<----
if HAVESVNWC
svn_dist_version: FORCE
@mysvnversion@ > svn_dist_version
endif
--8<----
This file is also generated unconditionally whenever you run "make all". However, the conditional "HAVESVNWC" makes sure the target appears in Makefile only if we are in a Subversion working copy. There are two additional things that we need to take care of. First, we have to make sure both version files are built in time, that is before the compiler runs:
--8<----
BUILT_SOURCES=svn_version.c svn_dist_version
--8<----
Then we have to make sure the file is distributed when we run "make dist":
--8<----
EXTRA_DIST=svn_dist_version
--8<----
This should finally give the desired results: in a Subversion working copy, svnversion inserts the proper revision in both the svn_version.c and the svn_dist_version file. In a copy untarred from a release or a prerelease, the svn_dist_version file (which contains the revision when the distribution was packaged) is read, but not created, and the contents are inserted into svn_version.c. The same happens in a working copy on a box that does not have Subversion installed (although I can't imagine how you'd ever get into this situation).
http://research.tannerpages...