将SVN的Revision自动写入头文件
 

2009-03-06 来源:qpsoft.com

 

版本管理是一件麻烦活、纯体力活。自从将软件使用SVN进行版本管理后,是头疼的一点就是如何将SVN的Revision号编译到主程序中:如果每次SVN的Revision号改变,都需要手式改头文件的话,也太麻烦了。

上网找,没看到有好工具:我觉得应该是一个很简单的事件,于是决定自己做。经过一下午的尝试,编写了一个小工具,来实现上述设想。该工具在Code::Blocks下测试通过,在VS下也是一个道理。

源码很简单:

/*
** Copyright (C) QPSOFT.COM All rights reserved.
*/

#include <stdio.h>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
if (argc != 4 && argc != 5)
{
printf("调用格式:autover 项目路径 文件名称 主版本号\n");
printf("例如:autover d:\\project\\life++ sdk/version.h 3.0.0\n");
return -1;
}

string revision = "0";
string date = "unknown date";
string svncmd("svn info ");
svncmd.append(argv[1]);

FILE* svn = popen(svncmd.c_str(), "r");
if (!svn) return -1;

char buf[16384] = {'0'};
fread(buf, 16383, 1, svn);
pclose(svn);

string info(buf);
int pos = info.find("Revision: ") + 10;
revision = info.substr(pos, info.find("\nNode Kind: ") - pos);
date = info.substr(info.find("Last Changed Date: ") + 19, 19);

string file(argv[1]);
file += "\\";
file += argv[2];

FILE* header = fopen(file.c_str(), "wb");
if (!header)
{
puts("Error: Could not open output file.");
return -1;
}

string version(argv[3]);
int dotOne = version.find(".");
int dotTwo = version.rfind(".");
string major = version.substr(0, dotOne);
string minor = version.substr(dotOne + 1, dotTwo - dotOne - 1);
string repair = version.substr(dotTwo + 1, version.length() - dotTwo);

fprintf(header, "/*\r\n** Copyright (C) QPSOFT.COM All rights reserved.\r\n*/\r\n\r\n");

fprintf(header, "#define DEF_VerMajor L\"%s\"\r\n", major.c_str());
fprintf(header, "#define DEF_VerMinor L\"%s\"\r\n", minor.c_str());
fprintf(header, "#define DEF_VerRepair L\"%s\"\r\n", repair.c_str());
fprintf(header, "#define DEF_VerRevision L\"%s\"\r\n", revision.c_str());

fprintf(header, "#define DEF_Version L\"%s.%s.%s.%s\"\r\n", major.c_str(), minor.c_str(), repair.c_str(), revision.c_str());
fprintf(header, "#define DEF_VerRcStr L\"%s, %s, %s, %s\"\r\n", major.c_str(), minor.c_str(), repair.c_str(), revision.c_str());
fprintf(header, "#define DEF_VerRcInt %s,%s,%s,%s\r\n", major.c_str(), minor.c_str(), repair.c_str(), revision.c_str());
fprintf(header, "\r\n#define DEF_VerState L\"%s\"\r\n", argc == 5 ? argv[4] : "");

fclose(header);

return 0;
}

比如在RC文件中使用:

/**
* Copyright (C) QPSOFT.COM All rights reserved.
*/

#include <windows.h>
#include "version.h"

1 VERSIONINFO
FILEVERSION DEF_VerRcInt
PRODUCTVERSION DEF_VerRcInt
FILEOS VOS__WINDOWS32
FILETYPE VFT_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "QPSOFT.COM"
VALUE "FileDescription", L"Life++ " DEF_VerMajor L"." DEF_VerMinor L" " DEF_VerState
VALUE "FileVersion", DEF_VerRcStr
VALUE "InternalName", "Life++"
VALUE "LegalCopyright", "Copyright ? 2006-2009 QPSOFT.COM"
VALUE "ProductName", "Life++"
VALUE "ProductVersion", DEF_VerRcStr
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 1033, 1200
END
END

比如我在Life++3.x工程中的使用:

引用
-------------- Build: sdk in life++ ---------------

Running target pre-build steps
autover Z:\project\life++\ sdk\version.h 3.0.0 alpha
pch.cpp
systeminfo.cpp
Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

点击这里下载文件:autover.zip


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织