views:

483

answers:

3

Hi,

I would like to know if there is a way to embed Mercurial tags into my C/C++ code. Basically I would like the tag string, which will end up being a release number (major.minor.rev), to be automatically inserted in a determined location of my C code as a static string.

The overall objective is that the application could be queried about its version number when executed with say a '-v' command line argument. Any alternative approach that doesn't involve trying to embed a Mercurial tag will be also welcomed as an answer.

BTW, I am using Code::Blocks on a Linux environment, so the solution can not rely on fancy VStudio features.

Thanks!

A: 

We use a macro for this

#define CVS(a) static const volatile char *rcsid = a;

....
CVS("$Id$")

CVS automagically expands $Id$. I assume this is what mercurial tags work as well.

Then we can use the strings command to find the exact version of each file in the executable / library etc.

You could use something similar.

static const volatile char *rcsid = "$Id"; //or whatever mercurial tag you want

int main() {

    .....
    std::cout << "Version is " << rcsid << std::endl;
}
Glen
If the $Id$ tag happened to have a stray `"` in it you would have trouble. You might try `#define CVS(a) static const volatile char *rcsid = #a;\ ... \ CVS($Id$);` instead.
Tim Schaeffer
@Tim Schaeffer, good catch, I posted from memory. Sometimes there's no substitute for good old copy/paste
Glen
well now you have the problem of the Id tag having a stray comma in it.
Logan Capaldo
+4  A: 

You will need the KeywordExtension to allow expansion of keyword entries, it is bundled with mercurial.

For instance to get support for $Id$ you could edit hgrc for you repo (.hg/hgrc) and add:

[extensions]
keyword =

[keyword]
# Enable expansion for the specific files
myfile.cpp =
# Enable for all .h files
**.h =

Then run

hg kwexpand

to expand keywords the relevant files, or

hg kwshrink

to shrink keywords.

You can even create your own keywords by adding the [keywordmaps] entry, e.g.

[keywordmaps]
User = {author|user}

Note: This disables the builtin keywords

More details on the extension can be found here: http://mercurial.selenic.com/wiki/KeywordExtension

amos
A: 

While it's OS X oriented, there's a blog post describing how to add version info into your buids (without RCS style keywords).

RyanWilcox
Thanks man! Actually I followed the 'Versioning with Makefile' strategy mentioned in that blog post and works nice.
Diego10