假设我有一些构建exe或dll文件的C ++项目。该项目被检入SVN存储库。我想自动将SVN的修订版本与我的exe / dll文件中嵌入的版本资源同步,即版本应该是 $ major。$ minor。$ svn_revision 。
关于如何实现这一点的任何想法?有没有开箱即用的解决方案?
答案 0 :(得分:11)
如果你安装了TortoiseSVN,那么随之安装了一个程序,SubWCRev
。
如果在您的文件中,您有此值:
$WCREV$
如果执行类似的操作,那么它将被最高提交的修订版号替换:
SubWCRev .\ yourfile.txt.template yourfile.txt
这将从yourfile.txt.template
复制,执行替换,并写入yourfile.txt
。
请注意,您可以使用许多其他宏,如果您在没有任何参数的情况下执行SubWCRev
,它会在控制台上列出所有宏。
答案 1 :(得分:3)
这非常有帮助,谢谢。如果对任何人有任何帮助,我已经为Visual Studio 2008改进了这个。
1 /在每个项目中创建/ Build文件夹
2 /将AssemblyInfo.cs作为AssemblyInfo.cs.txt复制到Build文件夹,将Build Action设置为“None”
3 /编辑AssemblyInfo.cs.txt以获得如下版本属性:
[assembly: AssemblyVersion("2.0.0.$WCREV$")]
[assembly: AssemblyFileVersion("2.0.0.$WCREV$")]
4 /在Prebuild事件中添加了以下内容:
SubWCRev $(SolutionDir) $(ProjectDir)\Build\AssemblyInfo.cs.txt $(ProjectDir)\Properties\AssemblyInfo.cs
每次编译时都可以使用。
我在Visual Studio 2008中使用VisualSVN / TortoiseSVN和VisualSVN Server。
<强>更新强>
我的同事刚刚更新了他的工作副本,而AssemblyInfo.cs则发生了冲突。看似很明显。我已经使用VisualSVN将其从SVN中排除以解决此问题。
答案 2 :(得分:3)
Program.X的答案效果很好。但是,我想补充一点,如果在提交更改之前构建可执行文件,则修订版将比正在运行的代码的实际修订版本号少一个。要缓解这种情况,您可以将版本设置为
"2.0.$WCREV$.$WCMODS?1:0$"
如果有任何局部修改,那么将在结尾放置1,如果没有则为0。因此,如果您稍后查看您的可执行文件并查看2.0.54.1,您知道它可能实际上是修订版55.
答案 3 :(得分:2)
您可能希望查看Subversion Properties和Subversion Keywords。他们没有解决资源问题,因为他们总是包含该死的$KeywordName: ...$
部分。自定义属性确实提供了一种很好的方法,可以在批处理文件中提供元数据,而不是。
无论如何,几年前我一直在寻找资源问题的解决方案而没有找到解决方案。因此,我们创建了自己的本土解决方案。我们更改了RC文件以包含在构建过程中生成的头文件。 RC依赖于标头,标头有一个自定义构建规则,它调用批处理文件来生成标头。以下代码段将从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
POPD
然后我们创建了一个名为component-info.h
的组件特定版本标题标题,其类似于:
#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)
#endif
最后,我们有一个产品系列版本文件,用于定义名为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)
#endif
然后,您的资源文件包含component-info.h
,并使用相应位置的各种定义(例如FILEVERSION MY_VERSION_NUMBER
)。这种结构在整个版本的冲压过程中给了我们很大的灵活性和可追溯性。它从批处理文件中的一个简单块变成了这个多层次的怪物,但在过去的几年里它对我们来说非常有效。
我发现很难相信没有人找到更好的方法来做到这一点。再说一次,我好几年都没有调查过它。我假设您可以添加一个自定义.rules
文件,该文件定义了一个处理此问题的自定义工具。