在CI中使用bjam构建项目
不知道什么原因,我的机器上什么VC2008命令行来编译项目,无论是devenv.com还是devenv.exe,都会占满CPU,而真正的编译进程cl.exe却一直慢吞吞地,几个文件的小项目,也不知要等上多少时间,在持续集成时实在忍无可忍。
不过因为之前有一段时间专门学习了一下如何使用bjam,所以我就决定在CI上,使用bjam来构建项目。统计了一下我的项目的情况,有用MFC的,有用WTL的,也有用wxWidgets的,有用VC编译的,也有用MinGW编译的,无论哪种情况,bjam都可以满足需求。
使用bjam的一个比较方便的特性是,它能比较智能地自动为不同的编译器套件使用各自的命令行编译选项,这样使得一个bjam脚本可以同时不同的编译器套件来编译。不过实际使用过程中,还是有些需要区别对待的地方,这可能是因为bjam主要用于boost的构建这个目的而产生吧。
比如对于VC和MinGW,可能链接的库文件是不同的,要么是文件名不同,要么是所在路径不同;链接选项可能不同,也许是boost的原因,bjam在构造exe时,默认是使用控制台子系统,所以需要自己在链接选项中自行指定使用Windows子系统,而该选项在VC和GCC中有细小的描述上的区别。
bjam的另一个比较方便的特性是,它能自动寻找编译器套件默认的头文件路径和库文件路径。这比使用makefile要方便太多了,比如在MinGW中编译一个C++,注意,是C++,不是C,的程序,需要仔细地设置引用路径,而bjam中完全不需要,只需要一行代码就能搞定:exe Hello : Hello.cpp ;这个特性对我的情况来说也是很有帮助的,比如使用MFC的项目,鬼知道它要引入多少头文件路径,还有就是有个工程设计成既可以用VC编译又可以用MinGW编译,所以这又省了不少事。
再扯一个跟bjam关系不是很大的东西,编译使用了wxWidgets的项目。有一个小工具程序,可以方便地得到指定路径中的wxWidgets在编译时使用的选项,那就是wx-config。通过这个小东西,在编写编译脚本时,又可以省掉不少事。在http://wxconfig.googlepages.com/上可以找到Windows的移植版本,不过在bjam中使用时,会有一点点小问题,就是它的输出内容都在最后添加了一个回车,而bjam并不能让用户方便地设定编译选项在命令行上的先后顺序,所以如果恰好它的输出结果被排在命令行的中间位置,那之后的那些选项就被断开了,shell则认为这是两条命令,所以会出错。好在这个Windows移植版本提供了源代码,下载下来,自己稍微修改一下,也就是在输出的那条语句中把最后的std::endl去掉就可以了。
VC在支持预编译头文件时,一般是指定stdafx.h文件,然后加个编译编译选项来实现。在bjam中不能这样直接加编译选项来达到这个目的,而是专门提供了一个叫cpp-pch的规则来实现。不过,对于只在CI上才执行的bjam命令,有没有这个功能都无关痛痒。
VC有个很好用的特性,auto-link,boost就使用这个特性,这也使得在VC上使用boost比在其他编译器套件中要方便,它默认链接的都是静态库,使得发布都省了一些事。在bjam中使用时,只要设定好boost库文件的路径,其他的就不用管了。
在使用了MFC的项目中,会有一些特定的选项,比如它需要再指定程序的入口,这些工作本来都是IDE默默地在后台完成了,使用bjam时就需要自己留心了,一般的做法就是直接看项目属性中的命令行一栏,把一些个性化的设置都提取出来写到bjam编译脚本中去。