Monday, October 12, 2009

Generating Automatic Version Numbers

All of my projects use a special version numbering scheme - major.minor.revision.build - revision is the Subversion revision and build is a build number based on the current date. Whenever I build a project I want this version number to be updated automatically (if it has changed), but making this work using QMake isn't obvious ... but once you know how, it could be used for a variety of different uses.


I have a special Qt-based EXE project that generates the version number by creating a version.h file that looks something like this:

#ifndef VERSION_H
#define VERSION_H

namespace Version
{
static const int MAJOR = 1;
static const int MINOR = 2;
static const int REVISION = 2572;
static const int BUILD = 15280;
}

#endif // VERSION_H

I then #include this header where necessary. The EXE is passed the major/minor version number and the name of the output file (e.g. version.h) and it extracts the SVN revision and generates the special build number. I'll spare you the code - all you need to know is how to ensure this EXE is launched each time I build a project that requires it.

First, I use a subdirs project that contains the version-generator .pro file, ensuring I have a version.exe file to execute. Then, in my main apps .pro file I have something like this:

MAJOR = 1
MINOR = 2
VERSION_HEADER = ../version.h

versiontarget.target = $$VERSION_HEADER
versiontarget.commands = ../version/debug/version.exe $$MAJOR $$MINOR $$VERSION_HEADER
versiontarget.depends = FORCE

PRE_TARGETDEPS += $$VERSION_HEADER
QMAKE_EXTRA_TARGETS += versiontarget

The MAJOR and MINOR definitions are changed by hand when required, the rest is automatic. The key part here is the FORCE keyword - this is poorly (if at all?) documented and ensures that the QMAKE_EXTRA_TARGETS command works every time. Extending this scheme to run additional targets would be simple - create another 'target' type and add it to the list (for example, you may want to launch a shell script that generates some code, etc.)

Getting this to work involved a lot of StackOverflow/Qt-list posts - I hope you find it useful.

0 Comments:

Post a Comment