10

我正在维护一个相当大的遗留应用程序。源代码树真是一团糟。我正在尝试设置构建服务器。

在源代码树上,我有带有源代码的第三方组件(也在项目的包含路径中)。这些组件也安装在 IDE 中。

我的问题是:如何管理这些组件?

我想以这种方式管理:

  • 在构建服务器上安装 IDE
  • 安装所有第三方组件
  • 从项目源树中删除组件源(并将它们保存在项目根目录中的每个压缩的专用文件夹中)
  • 每次我们需要自定义(或调试)第三方组件时,我们都会重新构建包并将其重新安装在构建服务器的 IDE 中(以及每个开发人员工作站上)

在 IDE 中安装组件和在包含路径中安装源代码有什么区别?链接器如何处理这种情况?

4

4 回答 4

22

我们已经使用简单的命令文件设置了我们的日常构建。

  1. 每个项目 (.dpr) 都有一个关联的 Build.cmd 文件。
  2. 所有 Build.cmd 文件都是从我们的主 BuildServerRun.cmd 文件中调用的。

BuildServerRun.cmd 文件负责

  1. 删除构建服务器上的整个源代码树。
  2. 从我们的源代码控制存储库获取最新版本。
  3. 调用每个 Build.cmd 并将输出通过管道传输到文件。
  4. 将结果邮寄给所有开发人员。

外部组件的所有路径都在 dcc32.cfg 文件中配置

..    
-u"c:\Program files\Developer Express Inc\ExpressInplaceEditors\Delphi 5\Lib"
-u"c:\Program files\Developer Express Inc\ExpressQuantumGrid\Delphi 5\Lib"
..
-r"c:\Program Files\Borland\Delphi5\Lib"
-r"C:\Program Files\jvcl\jvcl\resources"
..
-i"C:\Program Files\jvcl\jvcl\run"
-i"C:\Program Files\jvcl\jcl\source"

Build.cmd 示例。

注意:我们有一个策略来编译到 bin\dcu,exe 到 bin,因此是 -N,-E 指令。

@echo on
dcc32speed -B -Q -W -H -Nbin\dcu -Ebin BpABA.dpr
@echo off

截断的 BuildServerRun.cmd 示例

SET %Drive%=E:

:BuildServer
REM *************************************************
REM     Clear files
REM *************************************************
ECHO. > "%Temp%\BuildLieven.txt"
ECHO. > "%Temp%\TestRunLieven.txt"

REM *************************************************
REM     Set start time
REM *************************************************
echo | TIME | FIND "Huidige tijd" > "%Temp%\ResultLieven.txt"

REM *************************************************
REM     Get latest versions
REM *************************************************
IF %LatestVersion%==1 CALL %Drive%\buildserver\latestversion.cmd
ECHO "Latest versions opgehaald" >> "%Temp%\ResultLieven.txt"

REM *************************************************
REM     Build projects
REM *************************************************
CD %Drive%\Projects\

ECHO ***************************************************************** >> "%Temp%\BuildLieven.txt"
ECHO BpABA >> "%Temp%\BuildLieven.txt"
ECHO ***************************************************************** >> "%Temp%\BuildLieven.txt"
CD %Drive%\Projects\BPABA\production
ECHO Building BPABA\production
CALL Build.cmd >> "%Temp%\BuildLieven.txt"
CD %Drive%\Projects\BPABA\test
ECHO Building BPABA\test
CALL Build.cmd >> "%Temp%\BuildLieven.txt"
CD %Drive%\Projects\BPABA\test\dunit
ECHO Building BPABA\test\dunit
CALL Build.cmd >> "%Temp%\BuildLieven.txt"
ECHO BPABATests >> "%Temp%\TestRunLieven.txt"
ECHO Running BPABATests
CALL bin\BPABATests >> "%Temp%\TestRunLieven.txt"
CD %Drive%\Projects
ECHO. >> "%Temp%\BuildLieven.txt"
ECHO. >> "%Temp%\BuildLieven.txt"
ECHO. >> "%Temp%\BuildLieven.txt"

REM *****************************************************************
REM     Gather (Fatal)Errors/Hints/Warnings & Failures
REM *****************************************************************
ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO (Fatal)Errors/Hints/Warnings en Failures >> "%Temp%\ResultLieven.txt"
ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO Fatal errors during build >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND /c "Fatal:" >> "%Temp%\ResultLieven.txt"


ECHO Errors during build >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND /c "Error:" >> "%Temp%\ResultLieven.txt"

ECHO Warnings during build >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND /c "Warning:" >> "%Temp%\ResultLieven.txt"

ECHO Hints during build >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND /c "Hint:" >> "%Temp%\ResultLieven.txt"

ECHO Failures during test >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\TestRunLieven.txt" | FIND /c "Failures:" >> "%Temp%\ResultLieven.txt"
ECHO. >> "%Temp%\ResultLieven.txt"

ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO Controle #Projecten = #Compiles >> "%Temp%\ResultLieven.txt"
ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO #Projecten >> "%Temp%\ResultLieven.txt"
TYPE "%Drive%\buildserver\buildserverrun.cmd" | FIND /i "cmd >> " | FIND /i "Lieven" | FIND /i /v /c "FIND /i /v /c" >> "%Temp%\ResultLieven.txt"
ECHO #Compiles >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\buildLieven.txt" | FIND /i /c "dcc32" >> "%Temp%\ResultLieven.txt"
ECHO #Tests expected to run >> "%Temp%\ResultLieven.txt"
TYPE "%Drive%\buildserver\buildserverrun.cmd" | FIND /i "TestRunLieven" | FIND /i "CALL" | FIND /i /v /c "FIND /i /v /c" >> "%Temp%\ResultLieven.txt"
ECHO #Tests actually run >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\TestRunLieven.txt" | FIND /i /c "DUnit / Testing" >> "%Temp%\ResultLieven.txt"
ECHO. >> "%Temp%\ResultLieven.txt"
ECHO. >> "%Temp%\ResultLieven.txt"

ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
ECHO Detail (Fatal)Errors/Hints/Warnings en Failures >> "%Temp%\ResultLieven.txt"
ECHO ***************************************************************** >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND "Fatal:" >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND "Error:" >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND "Warning:" >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\BuildLieven.txt" | FIND "Hint:" >> "%Temp%\ResultLieven.txt"
TYPE "%Temp%\TestRunLieven.txt" | FIND "Failures:" >> "%Temp%\ResultLieven.txt"

REM *************************************************
REM     Set stop time
REM *************************************************
ECHO | TIME | FIND "Huidige tijd" >> "%Temp%\ResultLieven.txt"

REM *************************************************
REM     Send results
REM *************************************************
CALL %drive%\buildserver\Blat.cmd
于 2009-06-19T09:58:54.103 回答
3

我的回答比 Lieven 的回答更笼统,后者是 Delphi 特有的。我在问题后不久写了这个,但在提交之前去了一位同事;)

我拒绝在我们的主要 Windows 构建代理上安装任何 IDE。对我来说听起来像是一场噩梦。MSBuild 引擎可以很好地处理所有构建方案,除了 .NET,您只需要安装 Windows SDK。或者你可以使用 NAnt 甚至 CMake,无论如何。只是不要安装 IDE。构建服务器并不好玩。

现在您已将其标记为 Delphi。我不知道它在那里工作得有多好,但正如 Lieven 所写,Delphi 带有一个命令行编译器。我只是没有任何使用第三方组件的经验,但我认为 Delphi 在最新版本中支持 MSBuild。

我也不确定将第三方组件包含到版本控制中是否是一件好事,因为它占用的空间 - 尽管您也可以将它们放在其他地方并将它们作为外部包含,这使得它更小,但也强加了升级一个应用程序的组件将升级所有应用程序的问题 - 所以你最好有良好的集成测试。但这无论如何都是构建服务器的重点。

除此之外,签出并拥有构建应用程序所需的所有组件总是一件好事。如果组件做得好,您不需要将组件安装到 IDE 中。根据它们是什么组件,在许多情况下,您甚至不需要在开发人员机器上安装它们。例如,当您添加对它们的引用时,许多 .NET 组件在设计器中可用。许可通常只是“将许可文件放入同一目录”。嗯,至少应该是这样。如果这不是它在今天的 Delphi 中的工作方式,那可能是 Delphi 即将退出的原因之一。除了 Borland/Inprise/DevCo/Codegear/Embarcadero 的麻烦之外。

于 2009-06-19T10:25:45.220 回答
1

这里也有类似的情况,幸好一开始并没有一团糟。确实,真正的问题在于 IDE 配置,如果您检查旧版本,则需要指向第三方组件的正确版本。我听说的唯一解决方案是针对不同的产品发布配置使用不同的注册表分支。

组件保存在单独的目录结构中,并尽可能在目录名称中使用版本号。这样可以更轻松地检查旧版本并使构建脚本指向正确的版本。

多年来,我们一直使用 Apache Ant 作为主要构建工具,它确实可以满足我们的一切需求,包括单元测试调用和 Innosetup 脚本生成。

仅当您使用 BPL 发布可执行文件时才需要编译包,否则在构建服务器上不需要编译。

在构建服务器上也不需要在 IDE 中安装组件。

于 2009-06-19T09:48:13.750 回答
0

您可以使用Owly CI工具。

它允许通过定义清单文件以简单的方式构建项目。它还允许处理依赖项——您可以将 3rd 方组件包装在 owlyci 包中,并将它们标记为对主项目的依赖项。

有一个例子,如何将它与 Jenkins CI 系统一起使用。

于 2013-05-17T11:04:26.957 回答