add mercurial version info to xcode project

April 21, 2009

I’ll describe one way of adding mercurial version information automatically to an xcode project.

I recently switched from subversion to mercurial. I know, I should’ve done this years ago, don’t think I’m not kicking myself for it… mercurial is awesome (so is git, but I had to pick one.)

While I don’t really care about updating my source file comments with the revision number (I guess this is called CVS/RCS-style keyword substitution), I do like to have access to the revision number during the build process so I can add the revision number in some hidden spot of my application (one reason is to make sure that testers have the correct build- hate chasing already fixed bugs from old builds.)

The mercurial wiki suggests defining a directive in the Makefile. But xcode has it’s own build system and doesn’t use Makefiles (in normal circumstances.) Nor did I find a dynamic way to update OTHER_CFLAGS during build process.

My solution automatically generates a header file where a couple constants are defined. The header looks like this:

#define kHgGlobalRevision @"900b0f65d8f8+"
#define kHgLocalRevision @"6+"
#define kHgBranch @"default"
#define kHgTags @"tip"

All the information I need! I decided to define NSString constants as this information will usually be appended to other NSStrings.

The header file is created by a Run Script build phase. To add this build phase, right click on the target, and select Add > New Build Phase > New Run Script Build Phase:

add runscript build phase

add runscript build phase

I renamed the build phase to Run Script (hgversion) so I can easily find it later. Also, move this build phase to the top; we want this build phase to run before any other:

runscript build phase at top

runscript build phase at top

To edit the script, open the info window for the run script build phase (command-i is the shortcut 😉 and type in the shell script to query the version numbers and output to hgversion.h:

hgversion runscript info

hgversion runscript info

Here’s the script for copy and paste:

# echo hg revision information into hgversion.h (overwrites old file)

echo "#define kHgGlobalRevision @"\"`/opt/local/bin/hg id -i`\" > hgversion.h
echo "#define kHgLocalRevision @"\"`/opt/local/bin/hg id -n`\" >> hgversion.h
echo "#define kHgBranch @"\"`/opt/local/bin/hg id -b`\" >> hgversion.h
echo "#define kHgTags @"\"`/opt/local/bin/hg id -t`\" >> hgversion.h

As you can see the version numbers are output to hgversion.h. The old file is overwritten.

Add the header file to your project and use the constants as you wish!

One Response to “add mercurial version info to xcode project”

  1. Awesome!

    Thanks a ton for sharing this 😉

Leave a Reply