Auto-increment build number in a Visual C++ Express 2012 project

Microsoft Visual C++ Express 2012 for Windows Desktop

Lately I’ve been working on a custom game engine using Microsoft Visual C++ Express 2012 for Desktop. The project compiles into a dynamic library that will be linked to the main application that defines the game. The thing is I wanted to keep track of this engine version. I placed a major and minor version numbers, but I also, for the sake of curiosity, keep a build number. This number should increment every time a successful build of the project is performed. It will be reset when the minor version changes. That way I can keep track of how many different builds the project has have to a given major and minor version.

Obviously, I don’t want to manually increment that number. I could forget to do it, but more importantly, it will bore me. I’m really lazy. There are some free add-ins for Visual C++ that provides this feature out of the box (example). Unfortunately, the Express edition of Visual c++ does not allow you to install non-Microsoft add-ins, so it’s not a solution for me.

This post will summarize an alternative process I followed to achieve this automatic increment of the build number. It works on Visual C++ Express 2012 but I’m pretty sure it can also be applied to previous versions. This specific solution requires Git Bash because it involves the execution of a small Bash script. I’ve chosen Bash because I feel comfortable with it from my days of GNU/Linux, but any other (minimally powerful) script interpreter could work. I’ve chosen Git Bash because I already have it installed in my system as part of the Git for Windows package. The rough picture of the solution is:

  1. Store the build number in a header file, for example version.h.
  2. Create a script that increments a #define macro in version.h.
  3. Execute this script every time Visual C++ performs a successful build.

It will be important to make sure the modified file timestamp corresponds to the original one in order to prevent having to build the project just for that.

Header file

In my case, the header file is very simple and looks like this:

#pragma once

#define _MYPROJECT_MAJOR 0
#define _MYPROJECT_MINOR 1
#define _MYPROJECT_BUILD 1

Although macros must be avoided at all cost, in this case it is the easier way to show this solution.

Script

The script looks like this:

#!/bin/sh

# starts in $(ProjectDir)
# example /C/documents/solution/project/

# first step
awk '$0 !~ /#define _MYPROJECT_BUILD/ { print $0 }
     $0  ~ /#define _MYPROJECT_BUILD/ { n = $3 + 1; print $1 " " $2 " " n }' 
	 version.h > version_temp.h	 

# second step
touch -r version.h version_temp.h

# third step
cp -p version_temp.h version.h
rm -f version_temp.h

It is divided in three tasks:

  1. Increment, replace, and print the modified version.h to a temporal file using awk.
  2. Keep the original timestamp for the temporal file using touch.
  3. Rename the temporary file to the original one using cp and rm.

The first task is performed by the awk script. You can read the manual for a full description. It basically prints all lines of version.h which don’t match the string “#define _MYPROJECT_BUILD”. For the lines that match that string, they find the value in the third column (columns are separated by spaces), add one, and then reprint the line. Notice that the script could need adaptation for your particular implementation.

The modified version.h file is stored in version_temp.h. We don’t modify the file in place because we want to keep track of the original timestamp of the file. This is needed so Microsoft Visual C++ does not notice the file has been updated and thinks the project needs to be updated. The timestamp of the original file is copied to the temporal file by the touch command.

Then, we copy the temporal file to its final destination preserving all the relevant information (timestamp) using the -p modifier in cp. Finally, we remove the temporal file.

Hook the script

In order to execute the script every time Visual C++ successfully builds a project you must hook the script to the post-build event. You can find this right-clicking in your project and then “Properties”. This will open the project property pages. Navigating to the “Configuration Properties” -> “Build Events” -> “Post-Build Event” in the left panel you will see something like this:

Post-Build Event Dialog

In the command line parameter I’ve written the following:

"C:Program Files (x86)Gitbinsh.exe" --login ../tools/post-build

This calls the Git Bash interpreter (sh) defining all the environment variables (–login) which in turns calls our script (post-build). My directory layout is:

SolutionDir
   --> ProjectDir
          --> version.h
   --> tools
          --> post-build

Notice that the post-build event is executed from the project directory  (SolutionDirProjectDir in my case) . That’s why the script refers directly to ‘version.h’ and ‘version_temp.h’ while the post-build hook refers to ‘../tools/post-build’.

Conclusion

And that’s it. Every time the Visual C++ project is successfully built the post-build script will update the ‘_MYPROJECT_BUILD’ macro value. In addition, as the timestamp of the file is preserved in the process, this change doesn’t trigger a project rebuild of the version-dependent files. Keep in mind, however, that to update the build number in the application you will have to force a rebuild of the system. Don’t forget that when you want to release a particular build of your application.

 

About

View all posts by

2 thoughts on “Auto-increment build number in a Visual C++ Express 2012 project

Leave a Reply

Your email address will not be published. Required fields are marked *