« 一些琐事 | 返回首页 | 大恩莫言谢 »

make 使用笔记

我们的项目使用的构建工具,从今年初开始,从 boost jam 转移到 gnu make 。

makefile 写起来并不是一件轻松的事情,但是 make 的规则比 jam 要简单许多(比 boost jam 更简洁易懂),很符合 unix 的 KISS 美学。学会用 make 以后,编程方式可以得到极大的扩展,比用 IDE 的时代要灵活许多。尤其是可以用大量的使用自生成代码,或是用工具去生成数据文件,这些在 IDE 里做会相对麻烦。我们的开发,也不用局限在少数几种语言上了。

make 这个工具,我基本上是边学边用的,遇到什么问题临时想个方法弄一下。这最终导致 makefile 看起来很丑陋。但没有关系,写 makefile 跟写程序一样,以后可以不断重构。况且使用 makefile 本身,就很容易做任何自动化的工作了。

今天随便写几个最近遇到的问题,以及解决方案。

跨平台的问题

我们的项目是跨平台的,自然我希望一套代码可以在各种平台下都能通过编译。所以我希望 makefile 里可以识别出具体平台。

Windows 平台的识别比较简单,我们不打算支持 Windows 9x 下编译(但可以在 Win9x 运行)。Windows NT 下,似乎可以读到一个环境变量 OS = Windows_NT 。识别出这个就一定是 Win32 平台了。

Posix 兼容的系统中,大部分代码是可以直接编译的,少部分还需要区分一下具体平台版本。通常会有一个环境变量叫做 OSTYPE ,可惜这个变量里放的是 OS 的具体版本号,比如我的桌面系统就是 freebsd6.2 。Linux 系统下似乎也会带上版本号。

后来我们换了个方法,改调用 shell 指令 uname 来解决这个问题。在 makefile 里写上 OS=$(shell uname) 即可。Freebsd 下是 FreeBSD ,Linux 下统一是 Linux 。

用管道生成数据文件的问题

我们项目中几乎所有的数据文件,都要求在开发期使用人眼可读的文本。这个决定是前几个月才做的,但是这几个月的应用中已经几次获益。人眼可读的文本总是可以很快发现许多开发工具的 bug ,一旦生成的数据有文件,找出来非常容易。

但是由于种种原因(不一定是效率原因),最终我们用到的数据文件可能还需要多最初的文本做一些有限的格式转换。所以我们写了一些数据转换的工具。

不仅如此,我们还有一些源代码生成器,也是需要处理一些文本,生成一些目标数据的。

在我们的项目里便有了许多的文本处理工具,有些可以借用 unix 下的现成工具,有些需要自己写。自己写的那些,为了代码简洁,我们通常没有实现太多的命令行参数,而仅仅用标准输入输出来处理数据。最终看起来是这样的:

cat xxx.src | my_processor.exe > xxx.obj (windows 下则用 type 代替 cat)

my_processor.exe 是我们自己实现的文本处理器,有时候这个处理器没有被正常生成出来,或者本身处理出错,会导致不能正确的生成 xxx.obj 。

make 会因为程序运行出错而中断 make 流程,但是管道操作却有个特性:无论你程序是否正常退出,管道重定向的目标文件一定会被 shell 创建出来。也就是说, xxx.obj 一定会被创建出来,当出错时,它是一个长度为 0 的空文件。

这种情况下,第 2 次 make ,就会因为 xxx.obj 已经存在,而不会重新 build 它这个目标。

为了解决这个问题,我采用了这样一个做法:

cat xxx.src | my_processor.exe > xxx.obj.tmp && mv xxx.obj.tmp xxx.obj ( Windows 下用 type 代替 cat ,用 move /Y 代替 mv )

一旦中间出错,只会生成临时文件 xxx.obj.tmp 而不会产生 xxx.obj 了。


btw, 前几天鼓动同事在他的笔记本上装了 Ubuntu ,还是很不错的,他已经决定放弃 Windows 了。我不喜欢用本本,继续用 freebsd 做桌面好了。

微软应该不担心开源社区的人鼓捣 gcc kde gnome 这些东西,因为用 windows 的人永远会觉得 VC 更好用,Windows 桌面更强。Firefox 和 opera 能抢下 IE 的部分市场,也只是因为 IE 的安全性实在是值得担忧。真正对 windows 造成威胁的是越来越多的面对最终用户的应用程序可以在其他桌面系统上运行。比如我们正在开发的游戏。

我不反对 Windows ,但是我希望这个世界能有更多选择。

Comments

不知道开发的是什么游戏啊,期待啊,linux能玩的游戏不多!

automake , autoconf 系列工具很好用嘛, 在linux 上build的话

bjam 的跨平台是以一个几乎蛮干的手法做出来的。也就是每个平台写一大套配置。但是从 boost 精神上,又希望得到比较好的抽象层。其结果就是,整体设计相对复杂。仔细阅读代码你还会发现,其实它对 vc 还做了一些 work around 的方案,只是不那么明显罢了。

我们知道,想保持良好的抽象的同时,满足100 个需求和满足 10 个需求的设计复杂度是不同的。如果你的项目不需要需求上的扩展,或者和 boost 本身需求一致,那么用 bjam 好了。最好可以跟近它的开发。(我们当初就是这么做的)

否则,给个不用 make 的理由?


非常感激您拨冗答复!

我们项目不大,不到10w行,团队也不大,4人(包括一个phper),要跨平台,要自动测试自动构建,以后还想自动生成文档,考虑到bjam本身跨平台,脚本功能较强,内建支持编译工具多,而且我们项目中较多用到boost,bjam可以比较完美的将boost相关模块包含进来。

另外就是,由于这个项目公司给了比较大的自由度,所以才敢冒风险使用并不熟悉的bjam,也想趁这次项目,顺便整理出一套比较好的开发测试流程作为公司以后项目开发的模板。

虽然目前bjam一切工作正常,但是担心项目进行到中后期出问题,所以特别想知道您遇到过一些什么具体问题。

当你把项目构建自动化也当成编程的一部分做时,编写 makefile 并不是一件辛苦事。毕竟你编写软件本身要花掉更多的时间和精力。

对比而言 bjam 提供的那些便捷性更适用于快速构建小项目,比如你在学习阶段一天一个小实验项目这样;或是在项目合作人数较多,大家不易统一 makefile 编写标准的时候用。

bjam 扩展非常复杂,虽然它已经考虑的面面俱到,但一旦你有了一些它没考虑到的犄角旮旯里的需求时,(完美的)扩展 bjam 就是噩梦。bjam 开发社区非常冷清,maillist 上难以得到迅速的反馈。

云风兄,你好!
我刚花了1周时间文档+摸索用bjam为整个项目搭好了框架,就看到了你的这篇文章:-(

你们的项目一开始使用bjam,后来决定换成make肯定事出有因,你们使用他的原因是什么呢,后来放弃的原因又是什么呢?bjam存在什么问题吗?
盼复,非常感谢!

试试scons

试一下cmake,不错的,你一定会更喜欢.

windows和linux都可以做得更好。

推荐考察一下MPC: http://ociweb.com/products/mpc

原本是用来为ACE生产各种平台下工程文件的,支持生成NMake文件,VC7工程,VC8工程,GNUMakefile,Makefile等等。
用它来生成ACE以外项目的工程文件,也挺好使的,可以试试。

题外话,

支持Mac么?呵呵

linux下用命令行确实是很高效工作,很灵活。但linux的桌面系统应该就比不上windows了吧。并且装软件也是比较麻烦,有时由于库的不兼容要搞很久。以前一直搞C, 最近想学一下java,选择了eclipse,在linux(gnome)下装起来能用,但有时会死掉,搞了几次,还是选择了在windows下装上了eclipse。学习嘛,还是希望能流畅地学习主要内容,不想为了环境的配置分神。

如果Linux下的游戏比Windows下多,可能用Windows的人就会减少一半

呵,我一直都是用的 make 工具,很方便。makefile 编写也很有技巧的,编写一个通用的,就可以重用了。对整个项目的 build 能够更加彻底而灵活的控制。

云风讲得好啊,这样可以使得要玩游戏的人不用回到windows平台了,很早就有这个想法,可能很多人也都有这样的想法,但估计做的就没几个人,几家公司了,无论如何我都相信,这件事一定会好有意义的,不会浪费时间的。
makefile学过,不过都快忘的差不多了,FREEBSD也玩,在他上面装过一个游戏服务器,玩过他的桌面,当时也想把它做成我的桌面环境,使劲装上各种常用软件,什么MPLAY,音乐播放器,都自己编译安装,让他支持RMVB格式视频,修正音乐播放器列表中文显示问题等,学vim使用,不过到最后,因为种种原因还是回到windows下面了,而且时间一长,学过的好多东西都忘了。

比较保险的做法是uname -s

云风没去CGDC么?

这样设计和实现出来的平台应该有最好的灵活性和扩展性吧,向追求完美的人们致意一下。请教一下大家,如果没有实际的项目,如何能把linux上的实践深入下去?

从商业角度来说,网络游戏在非Windows平台上几乎得不到什么利益.

很支持最后一句话

嗯,向你学习。学 vi 太难了。我考虑把 xemacs 的快捷键设得跟记事本一致,就可以考虑不用 VS 的 IDE 了。

我现在编译环境已经不用 VC 的 GUI 参数了。全用 bjam 了。因为我很少用外部的命令行工具,所以 bjam 对我来说还是比基于 shell 的 make 还是要方便些。

哈,我也给自己的本本装上了Ubuntu,用了有半个月了。
工作和linux一点关系没有(C#),我都是用VNC连接到台式机上操作VS的。
使用感受,Linux的桌面软件还是不容乐观的;但是它还真是一个提供给程序员的很好的平台。
现在在看那本著名的UNIX编程书看,很有感觉。

我不反对 Windows ,但是我希望这个世界能有更多选择。

----------------- 哈哈,gates可不这么想

Post a comment

非这个主题相关的留言请到:留言本