Maintaining version numbers

In our company, we have the following policy about version numbers:

  • Each release has an ID in the form major.minor.release.revision
  • major, minor and release are numbers, arbitrarily invented for marketing purposes. They are product-specific.
  • revision is the SubVersion revision number the release is built from, returned by SubWCRev.
  • Each executable or DLL in the same release of a product has the same 4 numbers in it, visible in its Properties dialog in Explorer in the “Version” tab. This tab takes the numbers out of a resource.

I set out to fulfill the requirements as non-redundantly as possible. First, I created a header file for each product defining the macros MAJOR, MINOR and RELEASE. Next, a project called “Versioning”, whose custom build step ran SubWCRev to produce a header file, “revision.h”, that defined the macro REVISION.

Then I wrote a template resource file, “VersionResource.h”, that used those 4 macros plus APPNAME and defined the version resource. It included “revision.h”.

Now all I had to do was for each application project to write a file called version.rc with the following 3 lines:

#define APPNAME "MyApp"
#include "MyProductVersion.h"
#include "VersionResource.h"

And of course make the project depend on the Versioning project.

There was only one problem here: Each time I built the solution, Versioning would be built, “revision.h” would be re-created, and this would cause the recompilation of all version.rc files and the relinking of all applications.

One solution was to run SubWCRev, but have it write its output to a temporary file, then compare the temp file to the current revision.h and overwrite revision.h only if they are different. This had one drawback, though: Sometimes none of the files used in an application would change, but it would have to be relinked because its revision number increased.

Instead, I excluded version.rc from build, made its compilation a pre-link step and added Version.res as an Additional Input file to the linker. As a downside, version.rc now had to be rebuilt before each link, but the link itself took much longer anyway.

So here is the complete solution:

  • A per-product “MyProductVersion.h” defining three macros
  • The Versioning project containing:
    • “RevisionTemplate.h” with the line
      #define REVISION $WCREV$
    • A custom build step running SubWCRev to produce “revison.h”
    • VersionResource.h, that includes “revison.h”
  • Version.rc per application, built in the pre-link step.

Later on I’ll blog on the C# version of this solution.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: