用Delphi制作BPL包
2007-6-21
背景
GCM3构造时间长的问题由来已久。伴随着时间的流逝,系统功能越来越强大,模块越来越多,目前仅GCM一项,需要编译的客户端dll达389个之多。在编译机上,一次完整的编译过程(GCM+GCC_PE)耗时更是长达100分钟。经常出现这样的情况:开发人员和测试人员并没有别的事情,就是在等待编译版本,比如发版前的完整构造,或者每日构造失败需要重新编译,这就浪费了我们很多宝贵的工作时间。
解决方案
GCM3构造过程的环节很多,主要包括源码下载、编译、数据库模板和升级脚本的生成、文件压缩和打包发布等。其中编译是一个重头,占到一半以上的时间。其中每个工程编译时间大约为7、8秒,这样仅GCM的客户端dll编译就需要40到50分钟时间。于是如何减少编译时间成为减少总构造时间的一个解决思路。
由于GCM本身框架结构比较庞大,模块里的类继承层次也比较多,很多重复性的代码都被提取出来放在基类中,但在编译过程中这些基类中的代码将会被不断的重复编译。比如有200个工程中的主窗体继承自基类TListDetailForm,该类定义于单元文件ListDetailFrm.pas中,那么在编译过程中ListDetailFrm.pas将被重复编译200次。同样,由于GCM框架结构中继承关系为:TListDetailForm -> TDataBaseForm -> TBaseForm -> TBlankForm,因此这些基类所在的单元文件都会被重复编译200次。
为了避免这种无谓的重复编译,我们可以把公共代码(包括基类所在单元以及一些公共单元)编译成一个独立的部分,其它的工程都引用它。这样公共部分的代码就只需要编译一次,大大减少了编译的时间。
Delphi提供了带包编译(Build with runtime packages)的机制来避免重复编译相同的源码,方法如下:在编译工程时勾选带包编译方式(位于Project -> Options… -> Packages ->Runtime packages),并把前面编译好的BPL添加到运行时包中。当然,这里的BPL就是包含公共代码的包。
这种做法优点:
1. 提高FinalBuilder编译速度,缩短编译时间。同时也提高了打包的速度;
2. 减小编译出来的文件(如exe和dll文件)大小,同时减小了安装程序的大小,顺便提高了安装速度;
3. 若基类或公共单元做了修改,某些情况下,可以避免所有模块重编一遍,只需把这个包重新编一下即可。