在应用程序版本中使用SVN修订号

10
在一个非.NET的VS2010解决方案中,我想将svn修订号包含在应用程序版本中。目前我们只使用VS解决方案/项目设置,不使用makefile。我想在编译时获取工作副本的修订号,并将其存储到一个变量中,以便稍后在代码中使用它来显示版本号。到目前为止,我已经成功地使用`svnversion`作为预构建事件获取了工作副本的最新版本。
"C:\Program Files\CollabNet\Subversion Client\svnversion.exe" -n $(SolutionDir)
在构建时,我可以看到正确的修订号被返回到output控制台。
现在的问题是,如何将这个值存储到一个变量中,在代码中使用?
我已经尝试定义一个预编译器变量(_SVNREV)并使用它来保存上述命令的结果,直接从pre-build事件框中获取,但这不起作用。
_SVNREV="C:\Program Files\CollabNet\Subversion Client\svnversion.exe" -n $(SolutionDir)
%_SVNREV%="C:\Program Files\CollabNet\Subversion Client\svnversion.exe" -n $(SolutionDir)
%_SVNREV="C:\Program Files\CollabNet\Subversion Client\svnversion.exe" -n $(SolutionDir)
$(_SVNREV)="C:\Program Files\CollabNet\Subversion Client\svnversion.exe" -n $(SolutionDir)

这些都实际上不起作用。

解决方案: 在VS环境中尝试更新变量没有任何进展,所以我选择了另一种方法,在构建前调用一个脚本,获取工作副本的svn版本,然后创建包含该信息的头文件。

这是svnrev.bat,如果有兴趣可以看看:

@echo off
set cmd="C:\"Program Files\CollabNet\Subversion Client"\svnversion.exe -n %1 "
set versionfile=%1/version.h
FOR /F %%i IN ('%cmd%') DO SET SVNVER=%%i

echo Detected program revision %SVNVER% in %1
echo #pragma once > %versionfile%
echo #define _SVNVER "%SVNVER%" >> %versionfile%

你是在问“svn关键字替换”吗?还是我误解了你的问题? - High Performance Mark
2
只有在将文件提交到svn时才会发生'svn关键字替换'。然后,svn将使用其值替换保留变量。但是,在这种情况下,这种方法不起作用。 - fduff
设置客户端的后更新和提交挂钩怎么样?TortoiseSVN 已经支持了。这些挂钩协同工作,更新相同的变量,即 SVN 版本。 - Dialecticus
此外,还请参考这个可能相关的问题的答案:https://dev59.com/yU3Sa4cB1Zd3GeqPvn5f - Dialecticus
4个回答

6
到目前为止,我想到的最好的猜测是在预构建事件中生成一个包含svnversion的头文件。例如,我创建了一个批处理脚本version.bat
@echo off
FOR /F "tokens=*" %%i IN ('call svnversion') DO echo #define SVNVERSION "%%i" > svnversion.h

无论我想从哪里获取svn版本,我只需要简单地#include "svnversion.h"


3

如果你正在进行构建,你应该有一个标准的构建系统。我推荐使用Jenkins。它是开源的,易于使用。

Jenkins拥有的一个很棒的技巧是为您插入一些不错的环境变量供您使用:

  • SVN_REVISION - Subversion版本号
  • BUILD_NUMBER - Jenkins中的构建编号
  • JOB_NAME - Jenkins中的作业名称

一旦您开始使用Jenkins进行构建,后两个环境变量可能会比Subversion版本本身更有价值,因为后两个将把您的代码链接回项目,提供各种有用的信息。

Jenkins是一个持续构建引擎。您可以设置一个Jenkins作业,在命令、每当有检出或在某些时间进行构建。您甚至可以通过URL上的wget发送构建命令。

通过使用构建服务器,您消除了特定系统配置对构建产生某种副作用的可能性。构建服务器是已知的配置,并将生成您的正式构建。

这可能比您想知道的更多。(具体而言,您可以使用svnversion命令检索修订版本号,然后从那里继续)。但是,这将极大地改善您的构建过程。

谢谢,我们确实使用Jenkins。问题是这些变量只有在代码提交后才能在Jenkins中使用。而且这也是一个问题,你怎么在编译时将这些变量传递给源代码呢? - fduff
1
Jenkins不会检出代码并编译吗?这就是Jenkins插入修订号的时候。当开发人员进行构建时,我会检查是否已设置SVN_REVISION。如果没有,则设置为_dev build_。这样,我就知道构建是来自Jenkins(因此是官方的)还是来自开发人员。此外,在提交代码之前,您真的不知道修订版本。否则,您将获得开发人员从中检出但不包括其更改的修订号。 - David W.

1

您可以在批处理文件中运行命令。批处理文件可以生成一个名为version.h的头文件,其中包含版本字符串:

#define SVN_REV 12345

"#define SVN_REV " 是批处理脚本中的回显。SVN版本是从您拥有的命令中获取的。

现在,您可以将此头文件包含在代码中,并根据需要使用 #define。


1

我见过人们解析svn信息以获取版本号并将其写入文件,然后设置编译器将文件读入已编译的代码中。

关于SVN的棘手问题是:在旧版本中(每个子目录中都有一个.svn文件的版本),版本号仅保证对于项目根目录是正确的。任何其他目录都将承载该子树中最后一次提交的版本号。我不知道您使用的是哪个版本,但如果您使用的是几个版本之前的版本,请注意这一点!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接