views:

80

answers:

3

I would like the executables for a project I am working on to have the latest mercurial changeset recorded so that when a user complains about buggy behavior, I can track which version they are using. Some of my executables are Python and others are compiled C. Is there a way to automate this, or can you point me to projects that exhibit solutions that I can look at?

I am using autoconf in my project... in case that makes the solution easier.

Thanks!

Setjmp

+1  A: 

See wiki page on versioning with make

Hasturkun
The manpage for heirloom make says nothing about `$(shell)`, leading me to suspect that it is a GNUism. I will put forward an alternative solution in a separate answer.
Jack Kelly
+2  A: 

A common way to do this is with m4_esyscmd. For example, autoconf distributes a script in build-aux which generates a version number from the git repo and invokes AC_INIT as:

AC_INIT([GNU Autoconf], m4_esyscmd([build-aux/git-version-gen .tarball-version]), 
  [[email protected]])

You can often get away without distributing the script and do something simple like:

AC_INIT([Package name], m4_esyscmd([git describe --dirty | tr -d '\012']), 
  [bug-report-address])

Instead of git-describe, use whatever command you want to generate the version number. One important detail is that it should not have a trailing newline (hence the tr following git-describe).

A major drawback with this technique is that the version number is only generated when you run autoconf.

William Pursell
A slightly better option would be to only put real version numbers in `AC_INIT`, but use `AC_DEFINE` or `AC_DEFINE_UNQUOTED` to get the hg revision at configure time, rather than at autoconf time. Better still is to add a line in `Makefile.am`, so the correct hg version is defined at make time.
Jack Kelly
@Jack Unfortunately, doing so will only work when you build from a repository. If you unpack a tarball and run configure, the repository info is missing (unless you construct the 'dist' target to package the repo info in the tarball, but that's probably a bad idea.)
William Pursell
@William: Your observation is correct, but I have an alternate solution that uses `AM_CONDITIONAL` and checks for `$srcdir/.hg`. I've updated my answer.
Jack Kelly
+3  A: 

Add this to configure.ac:

AM_CONDITIONAL([IS_HG_REPO], [test -d "$srcdir/.hg"])

Add the following lines to Makefile.am:

if IS_HG_REPO
AM_CPPFLAGS = -DHGVERSION="\"$(PACKAGE) `hg parents --template 'hgid: {node|short}'`\""
else
AM_CPPFLAGS = -DHGVERSION=PACKAGE_STRING
endif

This will define HGVERSION as a string of the form APPNAME hgid: 24d0921ee4bd or APPNAME VERSION, if building from a release tarball.

Jack Kelly
This will only work if the repository information is included in the tarball. If we assume automake is in use, 'make dist' will not include that information, so this solution will not allow you to generate a usable tarball.
William Pursell
@William: I now check for `$srcdir/.hg` and believe that I avoid the problem you've raised.
Jack Kelly