Say I have some C++ project which builds an exe or dll file. The project is checked into a SVN repository. I want to automatically synchronize the revision from SVN with the version resource embedded in my exe/dll file, i.e. the version should be something like $major.$minor.$svn_revision.
Any ideas on how to achieve this? Are there any out-of-the-box solutions available?
-
If you have TortoiseSVN installed, then there is a program installed with it,
SubWCRev.If, in your file, you have this value:
$WCREV$Then it'll be replaced with the highest committed revision number if you execute something like this:
SubWCRev .\ yourfile.txt.template yourfile.txtThis will copy from
yourfile.txt.template, do the substitutions, and write toyourfile.txt.Note that there's a lot of other macros you can use as well, if you execute
SubWCRevwithout any arguments, it'll list them all on the console.Stefan : SubWCRev is also available separately for those who don't (want) to use TortoiseSVN: http://sourceforge.net/project/showfiles.php?group_id=138498&package_id=281312Lasse V. Karlsen : Cool, I didn't know that!Jim T : well thats my fact for the day :) -
You might want to look into Subversion Properties and Subversion Keywords. They don't solve the resource problem since they always include that damned
$KeywordName: ...$part. Custom properties do provide a nice method for making metadata available in batch files and what not.Anyway, I looked for a solution to the resource problem a few years ago and didn't find one. So, we created our own home-grown solution. We changed our RC file to include a header file that was generated during the build process. The RC was dependent on the header and the header had a custom build rule that invoked a batch file to generate the header. The following snippet will extract the current revision from the output of
svn info.SET rootdir=%1 SET svnrev=0 PUSHD "%rootdir%" FOR /F "tokens=1-4 delims=: " %%I IN ('svn info') DO ( IF /I {%%I}=={rev} SET svnrev=%%L ) (ECHO./* ECHO. * version-stamp.h - repository version information ECHO. */ ECHO.#ifndef VERSION_STAMP_H ECHO.#define VERSION_STAMP_H ECHO.#define REPOSITORY_VERSION %svnrev% ECHO.#endif) > include\version-stamp.h POPDThen we created a component specific version stamping header named
component-info.hthat looked something like:#ifndef component_info_h #define component_info_h #include "product-info.h" #include "version-stamp.h" #define VERS_MAJOR 1 #define VERS_MINOR 2 #define VERS_PATCH 3 #define VERS_BUILD REPOSITORY_VERSION #define MY_COMPONENT_NAME "TPS Report Generator" #define MY_VERSION_NUMBER VERS_MAJOR,VERS_MINOR,VERS_PATCH,VERS_BUILD #define MY_VERSION_STRING VERSION_STRING(VERS_MAJOR,VERS_MINOR,VERS_PATCH,VERS_BUILD) #endifFinally, we had a product-line version file that defined the product information named
product-info.h:#ifndef product_info_h #define product_info_h #define PROD_VERS_MAJOR 0 #define PROD_VERS_MINOR 1 #define PROD_VERS_PATCH 0 #define PROD_VERS_BUILD 0 #define VSTR1(s) #s #define VSTR(s) VSTR1(s) #define VERSION_STRING(a,b,c,d) VSTR(a) "." VSTR(b) "." VSTR(c) "." VSTR(d) "\0" #define MY_COMPANY_NAME "IniTech\0" #define MY_COPYRIGHT "Copyright ©2009 " MY_COMPANY_NAME #define MY_PRODUCT_NAME "\0" #define MY_PRODUCT_VERSION_NUM PROD_VERS_MAJOR,PROD_VERS_MINOR,PROD_VERS_PATCH,PROD_VERS_BUILD #define MY_PRODUCT_VERSION_STR VERSION_STRING(PROD_VERS_MAJOR,PROD_VERS_MINOR,PROD_VERS_PATCH,PROD_VERS_BUILD) #endifThen your resource file includes
component-info.hand uses the various defines in the appropriate places (e.g.,FILEVERSION MY_VERSION_NUMBER). This structure gave us a lot of flexibility and traceability in the whole version stamping process. It grew from a simple chunk in a batch file into this multi-leveled monstrosity but it has worked very well for us for the last few years.I find it hard to believe that no one has found a better way to do this yet. Then again, I haven't investigated it for a number of years. I would assume that you could add a custom
.rulesfile that defines a custom tool that handles this. -
This is great help, thanks. I've refined this for Visual Studio 2008 if it's of any help to anyone.
1/ Created a /Build folder within each project
2/ Copied AssemblyInfo.cs to the Build folder as AssemblyInfo.cs.txt, set the Build Action to "None"
3/ Edited the AssemblyInfo.cs.txt to have version attributes as below:
[assembly: AssemblyVersion("2.0.0.$WCREV$")] [assembly: AssemblyFileVersion("2.0.0.$WCREV$")]4/ Added the following to the Prebuild events:
SubWCRev $(SolutionDir) $(ProjectDir)\Build\AssemblyInfo.cs.txt $(ProjectDir)\Properties\AssemblyInfo.csThis works everytime you compile.
I am using VisualSVN/TortoiseSVN and VisualSVN Server with Visual Studio 2008.
UPDATE:
My colleague has just updated his working copy and AssemblyInfo.cs is conflicted. Seems obvious. I have excluded it from SVN using VisualSVN to resolve this.
0 comments:
Post a Comment