每日编译的入门实践

来源:互联网 发布:淘宝旺旺买家版官方 编辑:程序博客网 时间:2024/04/29 23:52

每日编译的入门实践

(作者:Jackey,网址:www.kuihua.net)

1      引言:

有关每日编译(Daily-BuildNight-Build)的讨论在网上已经很多,但大多都是停留在形式上或纯粹是一种谈资,很少看到一些真正有用的、可操作的东西。不过,网上倒是有很多开源的每日编译系统,ANTNANT等,感觉都是针对.netjava开发的,对常规的应用程序开发好像有点不是太适合,而且系统过于庞大,需要很多外围软件的支持。

鉴于此,本人利用BATPerl脚本实现了一个入门级的每日编译系统。

2      本文需要建立的工作环境:

2.1   系统运行环境:

l       开发环境:Visual C++ 6.0

l       打包环境:Install Shield 6.1

l       脚本环境:Active Perl 5.6.1

l       操作系统:Win2000/WinXP

l       CVS环境:WinCVS(1.3.13.1)CVSNT(2.0.4)

l       CVS设置::pserver:jackey@server:D:/KHBuild

l       CVS2CL:变更日志工具,是个Perl脚本,下载地址:http://www.red-bean.com/cvs2cl

l       环境变量:需要为Install Shield手工建立Path系统变量,其它工具会在安装时自动添加。

2.2   目录环境与例子工程设置:

l       测试工程在cvs中目录结构:

/TestProject/Source                                       // 测试工程源代码目录

/TestProject/Install                                        // 测试工程安装代码目录

l       每日编译目录环境设置:

D:/CVSBuild                                                 // 临时编译目录

D:/DailyBuild                                                // 每日编译目录

/Product                                            // 所有产品目录

/TestProject                               // 测试产品目录

/2004-9-1                            // 2004.9.1的产品

/2004-9-2                            // 2004.9.2的产品

/2004-9-3                            // 2004.9.3的产品

                               /BuildLog                                  // 所有产品的日志

                                     /TestProject                        // 测试产品的日志

/ChangeLog.txt                    // 测试产品的代码变更日志

/2004-9-1                            // 2004.9.1的编译日志

/2004-9-2                            // 2004.9.2的编译日志

/2004-9-3                            // 2004.9.3的编译日志

       /sys.log                        // 系统日志

       /cvs.log                        // cvs代码下载日志

       /vc6.log                       // vc6代码编译日志

       /install.log                    // 打包程序编译日志

                               /Script

                                       /cvs2cl.pl                          // 产生ChangeLogPerl脚本

                                       /FilePath.pl                       // 修改Install Shield的绝对路径的Perl脚本

                                       /LoadTest.bat                   // 用于Windows自动任务调用的批处理

                                       /BuildTest.bat                   // LoadTest.bat调用的实际自动编译脚本

3      BuildTest.bat的实现思路:

l       参数说明:

1.       指定编译中间过程存放的盘符。                   (如:D: )

2.       指定每日编译存放的盘符,可以是网络盘。 (如:E: )

3.       指定cvs所需要的代码仓库信息。

l       具体实现步骤:

1.       判断输入参数的合法性;

2.       得到当前日期,通常的格式为:2004-9-5

3.       设置环境变量,方便进一步的操作;

4.       进入脚本所在目录;

5.       删除当天编译过的目录,保证只留一份当天的产品;

6.       创建当天产品的存放目录;

7.       将当前的系统环境状态写入sys.log日志文件中;

8.       cvsnt中下载TestProjet的源代码和安装代码;

9.       使用cvs2cl.pl为下载后的代码产生代码变更日志(ChangeLog.txt)

10.     使用FilePath.pl修改安装代码里的绝对路径;

11.     使用msdev.exe编译TestProject工程;

12.     使用isbuild.exe编译TestProject的安装代码;

13.     将编译后的安装程序拷贝到指定的每日编译目录;

14.     删除一些不需要的临时目录;

15.     编译结束。

l       为了实现每日编译的自动化,需要建立一个Windows系统任务,让它在每天午夜的时候自动调用LoadTest.bat,实现真正意义上的Daily-BuildNight-Build

4      仅供参考的实现脚本:

4.1   LoadTest.bat实现参考:

BuildTest.bat D: D: jackey@server:D:/KHBuild

4.2   BuildTest.bat实现参考:

@echo off

 

REM ------- Check the input Param is validate!  --------

 

if "%1"=="" goto :Usage

if "%2"=="" goto :Usage

if "%3"=="" goto :Usage

 

echo Starting daily-build for TestProject product...

 

date /t > date.inf

for /F "tokens=1* delims=, " %%I in (date.inf) do set DATE=%%I

del date.inf

 

set PROJECT=TestProject

set BUILD_PATH=%1/CVSBuild

set SCRIPT_PATH=%2/DailyBuild/Script

set PRODUCT_PATH=%2/DailyBuild/Product/TestProject/%DATE%

set LOG_PATH=%2/DailyBuild/BuildLog/TestProject/%DATE%

set CVSROOT=-d:pserver:%3

set CODE_PATH=%BUILD_PATH%/TestProject

 

set SYS_LOG=%LOG_PATH%/sys.log

set CVS_LOG=%LOG_PATH%/cvs.log

set VC6_LOG=%LOG_PATH%/vc6.log

set INSTALL_LOG=%LOG_PATH%/install.log

set CHANGE_LOG=%2/DailyBuild/BuildLog/TestProject/ChangeLog.txt

 

cd /d %SCRIPT_PATH%

rd /s /q %PRODUCT_PATH%

rd /s /q %LOG_PATH%

 

md %BUILD_PATH%

md %PRODUCT_PATH%

md %LOG_PATH%

 

time /t >> %SYS_LOG%

date /t >> %SYS_LOG%

 

echo 工程名称     = %PROJECT%                  >> %SYS_LOG%

echo 产品路径     = %PRODUCT_PATH%     >> %SYS_LOG%

echo 编译路径     = %BUILD_PATH%           >> %SYS_LOG%

echo 代码路径     = %CODE_PATH%             >> %SYS_LOG%

echo 日志路径     = %LOG_PATH%               >> %SYS_LOG%

echo CVS参数     = %CVSROOT%                 >> %SYS_LOG%

echo CVS日志     = %CVS_LOG%                  >> %SYS_LOG%

echo VC6日志     = %VC6_LOG%                  >> %SYS_LOG%

echo 系统日志     = %SYS_LOG%                  >> %SYS_LOG%

echo 安装日志     = %INSTALL_LOG%         >> %SYS_LOG%

echo 更新日志     = %CHANGE_LOG%         >> %SYS_LOG%

 

echo [...Checkout Source Code...]                   >> %CVS_LOG%

cvs %CVSROOT% checkout -d %BUILD_PATH%/Source  TestProject/Source  >> %CVS_LOG%

echo [...Checkout Install Code...]                    >> %CVS_LOG%

cvs %CVSROOT% checkout -d %BUILD_PATH%/Install  TestProject/Install  >> %CVS_LOG%

 

echo [...Building ChangeLog for this version...]

cd /d %CODE_PATH%

%SCRIPT_PATH%/cvs2cl.pl --hide-filenames -P -f ChangeLog.txt

copy /Y ChangeLog.txt %CHANGE_LOG%

del ChangeLog.txt

cd /d %SCRIPT_PATH%

 

echo [...Building TestProject...]

msdev %CODE_PATH%/Source/TestProject.dsw /MAKE "TestProject - Win32 Release" /REBUILD >> %VC6_LOG%

echo [...Building Installshield code...]

FilePath.pl %PROJECT% %CODE_PATH% %CODE_PATH%/Install/ >> %INSTALL_LOG%

isbuild -m"Default" -p"%CODE_PATH%/Install/TestProject.ipr" -b"%BUILD_PATH%/Test" -r >> %INSTALL_LOG%

 

echo [Copy Install files to daily-build Repository...]

xcopy /Y %BUILD_PATH%/Test/DiskIm~1/Disk1/*.* %PRODUCT_PATH%

 

echo [Now, delete the temporary build-path...]

rd /s /q %BUILD_PATH%

 

goto :EOF

 

REM -------  Print the usage for this .bat file  --------

 

:Usage

echo ---------------------------------------------------------------------------------------------

echo +

echo +       %0 [Temp disk volume] [Dest disk volume] [user@server:path]

echo +

echo +   [    Example    ] : %0 D: E: administrator@localhost:D:/KHBuild

echo +   [Temp disk volume] : 指定编译中间过程存放的盘符。                (如:D: )

echo +   [Desk disk volume] : 指定每日编译存放的盘符,可以是网络盘。(如:E: )

echo +   [user@server:path] : 指定cvs所需要的代码仓库信息。

echo +

echo ---------------------------------------------------------------------------------------------

 

:EOF

4.3   FilePath.pl实现参考:

#!/user/bin/perl -w

 

my $search   = "=.*$ARGV[0]";                                 # Search value

my $replace  = "=$ARGV[1]";                                    # Replace value

my $dirname  = "$ARGV[2]File Groups";                    # Search directory

 

print "/r/n";

print "Search is /"$search/"/r/n";

print "Replace is /"$replace/"/r/n";

print "Directory is /"$dirname/"/r/n";

print "/r/n";

 

opendir DIR, $dirname or die "Cannot open $dirname: $!";           # Open directory

foreach my $filename (readdir DIR)                                            # Enumerate directory file

{

        next if $filename =~ /^/./;                                                    # Skip . and ..

        next if $filename =~ /CVS/;

        next if $filename =~ //.fdf/;

        $filename = "$dirname//$filename";                                     # Append directory path

        open(INFILE, "$filename") || die "cannot open $filename: $!";

        open(OUTFILE, ">$filename"."_bak") || die "$!";                 # Open and create file

        print "[ Processing file is /"$filename/"... ]/r/n/r/n";

        while( <INFILE> )                                               # Enumerate all lines                                            

        {

                s/$search/$replace/g;                                    # Search and replace in global

               print $_;                                                       # Print the replace result

                print OUTFILE $_;                                      # Save in new file

        }

        close INFILE;                                                     # Close in_file

        close OUTFILE;                                                 # Close out_file

        rename $filename . "_bak", $filename;                  # Rename out_file to in_file

}

closedir DIR;                                                               # Close the directory

5      每日编译的应用探讨:

5.1   建立核心链条思想:

源代码管理工具  => Bug追踪工具 => 每日编译工具

WinCVS/CVSNT  =>   Bugzilla   =>  BATPerl脚本

5.2   如何运用这些工具:

l       必须建立源代码的版本控制系统,就是cvs,基本的代码提交原则:

1.       程序员尽量每天只在下班前提交一次;

2.       提交的代码必须是在自己的机器上是正常运行的;

3.       每次提交都必须用简短的话说明自己提交代码的功能描述。

l       建立错误追踪系统,用Bugzilla就很好,配置好邮件系统,使Bugzilla成为测试人员与开发人员沟通的桥梁。

l       BATPerl脚本,以cvs中的源代码为核心实现简单的每日编译工具,将这个自己写的自动化工具放到一台专门的编译机器上,在每天的半夜开始自动下载代码,自动编译代码,自动打包安装程序,自动记录各种编译日志,自动将安装程序放置到一个固定的以日期为目录名的公共区。(用cvs2cl.pl得到程序员上传的代码更新日志,以便测试人员参考)

l       测试人员的第二天,应该到公共区取得头天的最新版本,并根据ChangeLog进行新版本的测试。并将测试中发现的Bug,通过Bugzilla反馈给程序员。程序员可以根据自己的情况,或公司的规定来决定修改这些Bug的时间。并将这些Bug的修改情况,在代码提交时,写入代码日志。

l       开发人员的第二天,应该到公共区查看编译日志,看看自己的模块是否正常编译,及时更正,看看自己的邮箱有没有Bug报告,及时修改。

l       管理人员的第二天,在综合项目需求与头天版本进度的基础上,可以判断产品的发展方向,如果有偏航或理解错误或有新需求时,可以根据当前情况及时调整。

l       这样,通过 cvs => bugzilla => daily-build,就能将程序员与测试员,进行互动,各施其责。减少沟通与人为的麻烦。对于管理层,也能做到心中有数:因为每天都有新版本,随时掌握产品的走向。。。等等。

5.3   本人写的相关工具的文档:

l       WinCVS/CVSNT的简明手则:

http://blog.csdn.net/ycw/archive/2003/12/29/4183.aspx

http://blog.csdn.net/ycw/archive/2003/07/18/4184.aspx

http://blog.csdn.net/ycw/archive/2003/07/18/4185.aspx

http://blog.csdn.net/ycw/archive/2003/07/18/4186.aspx

l       Bugzilla的安装实录:

http://blog.csdn.net/ycw/archive/2004/02/07/4187.aspx

http://blog.csdn.net/ycw/archive/2004/02/07/4188.aspx

http://blog.csdn.net/ycw/archive/2004/02/07/4189.aspx

http://blog.csdn.net/ycw/archive/2004/09/05/95076.aspx