We’ve covered how to automatically include the mercurial revision into the version. Now how about doing this for Subversion?
The basics of how to accomplish this are much the same as in the mercurial example. The major difference is that I don’t use WSH to generate the version file. Unlike TortoiseHg, which includes the CLI tools for Mercurial, TortoiseSVN does not. Therefore you have two choices:
- Download a CLI SVN implementation like SlikSVN and implement a script similar to the one that we did for Hg.
- Use the SubWCRev.exe utility that comes with TortoiseSVN to generate your version file from a template
Since I already use TortoiseSVN and SubWCRev has already done the heavy-lifting for me, I’ve decided to go that route. As usual, I’ll be doing my example using Visual Studio 2010 Professional although these techniques should work on other versions of VS as well.
The source code for this post is available here.
Step 1: Setup Basic Versioning
First we need to have the basic building blocks in place, as discussed in Versioning a Native C/C++ Binary with Visual Studio
Step 2: Add an SVN Version Template
Next we create a file named svn_version.h.tmpl in our project. I generally keep it under the Resources filter. This file serves as the basis of the SVN version header that we ultimately want to include in our project. The tokens (e.g. $WCREV$) will be automatically replaced by the SubWCRev utility later.
#ifndef _SVN_VERSION_H_ #define _SVN_VERSION_H_ #define SVN_LOCAL_MODIFICATIONS $WCMODS?1:0$ // 1 if there are modifications to the local working copy, 0 otherwise #define SVN_REVISION $WCREV$ // Highest committed revision number in the working copy #define SVN_TIME_NOW $WCNOW$ // Current system date & time #endif
Step 3: Add the Pre-build Step
Finally we need to add a pre-build step which will execute the SubWCRev tool, thus generating the svn_version.h file prior to the binary being built.
- Right-click on your project
- Select Properties
- Click Build Events
- Click Pre-Build Event
- In the Configuration drop-down, select All Configurations
- In the Command Line field, enter:
SubWCRev.exe $(SolutionDir) $(ProjectDir)\svn_version.h.tmpl $(ProjectDir)\svn_version.h - In the Description field, add a comment such as:
Generate the svn_version.h file with the necessary repo identify info for versioning
NOTE:If you have multiple projects in the same solution that all need to use the same information from Subversion you have a few choices. One is to put the template and pre-build event in one project which all the other projects depend on and add a link to the svn_version.h file that gets generated. Another option is to create a specific version project that all it does is generate the svn_version.h file and define common version information and then have every project in the solution depends on it so it’s executed first in the build order.
Step 4: Update Version.h
The version.h file we created in the basic versioning post needs to be updated to include the generated svn_version.h file and to make use of its defines.
#include "svn_version.h" #define STRINGIZE2(s) #s #define STRINGIZE(s) STRINGIZE2(s) #define VERSION_MAJOR 1 #define VERSION_MINOR 0 #define VERSION_REVISION 0 #define VERSION_BUILD SVN_REVISION #if SVN_LOCAL_MODIFICATIONS #define VERSION_MODIFIER "M" #else #define VERSION_MODIFIER #endif #define VER_FILE_DESCRIPTION_STR "Built " STRINGIZE(SVN_TIME_NOW) " from r" STRINGIZE(SVN_REVISION) #define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD #define VER_FILE_VERSION_STR STRINGIZE(VERSION_MAJOR) \ "." STRINGIZE(VERSION_MINOR) \ "." STRINGIZE(VERSION_REVISION) \ "." STRINGIZE(VERSION_BUILD) \ VERSION_MODIFIER #define VER_PRODUCTNAME_STR "c_svn_autoversion" #define VER_PRODUCT_VERSION VER_FILE_VERSION #define VER_PRODUCT_VERSION_STR VER_FILE_VERSION_STR #if LIBRARY_EXPORTS #define VER_ORIGINAL_FILENAME_STR VER_PRODUCTNAME_STR ".dll" #else #define VER_ORIGINAL_FILENAME_STR VER_PRODUCTNAME_STR ".exe" #endif #define VER_INTERNAL_NAME_STR VER_ORIGINAL_FILENAME_STR #define VER_COPYRIGHT_STR "Copyright (C) 2011" #ifdef _DEBUG #define VER_VER_DEBUG VS_FF_DEBUG #else #define VER_VER_DEBUG 0 #endif #define VER_FILEOS VOS_NT_WINDOWS32 #define VER_FILEFLAGS VER_VER_DEBUG #if LIBRARY_EXPORTS #define VER_FILETYPE VFT_DLL #else #define VER_FILETYPE VFT_APP #endif
Step 6: Add SVN Ignore on svn_version.h
Finally, we need to go ahead and add an svn:ignore on svn_version.h because we don’t want its difference checking in every commit and we don’t want it constantly marking the working copy as modified if it’s tracked.
Results
Now when each time you build your projects, the latest Subversion information of the working copy is automatically included in the file version information.
Final Thoughts
So there you have it, you can now automatically include all the necessary information from your Subversion working copy in your build to map them one-to-one with the source code that was used.
Other Posts in this Series
- Mapping Binaries in the Field to Source Code in the Repository
- Versioning a Native C/C++ Binary with Visual Studio
- Versioning a .NET Assembly with Visual Studio
- Integrating the Mercurial Revision into the Version Automatically with Native C/C++
- Integrating the Mercurial Revision into the Version Automatically with .NET
- Integrating the Subversion Revision into the Version Automatically with Native C/C++
- Integrating the Subversion Revision into the Version Automatically with .NET
15 thoughts