从Makefile看Being Textual的罪恶

来源:互联网 发布:向量旋转90度矩阵 编辑:程序博客网 时间:2024/04/28 09:28

看了好几天的《GNU Make项目管理》
makefile的规则虽然简单,但弄出一个能真正有效工作的makefile绝对超出大多数人的想象。
Makefile的目标:
1. 不用手工指定,让makefile自行推出文件间的依赖关系(即.cpp与它包含的.h文件,以及该.h文件中包含的其他.h文件间的依赖关系)。
2. rm了项目中的一个文件之后,makefile还能自动维护文件间的依赖关系(这些关系就记录在makefile中)。
为了实现这两个目标,这本书讨论来讨论去,先后提出若干种方案,但都有种种缺憾,最后的解决办法虽然能够工作,但hack的痕迹也太明显了,甚至为了支持这个trick(即为每个prerequisites增加一个假象的空target,号称是automake那帮人发明的),连gcc也增加了一个莫名其妙的选项-MP(hack啊hack)。
如果main.cpp包含了f.h,main.cpp对于f.h的依赖关系就应该被记录下来。
如果原来main.cpp依赖于f.h,但后来f.h从项目中去掉了,main.cpp对于f.h的依赖关系就应该随之被去掉。
这种依赖关系记录在什么地方?makefile中。
这些依赖关系是自动生成的,因为人工指定工作量太大。
去除某些依赖关系的工作也是自动的(人工做的工作就是从目录中rm这个被其他文件依赖的文件),同理。
所谓自动,就还是由makefile自己来做。
根据依赖做事,维护依赖关系,这两件事情现在都是由makefile来做。
而且还想只运行一遍make就什么都干了:
在依赖关系的指导下更新依赖关系,然后根据更新后的依赖关系做事。
也就是:
在makefile的指导下更新makefile(其实是更新include进来的记录着依赖关系的.d文件),然后根据更新后的makefile做事。
为了实现第一个目标,make在更新了依赖关系之后就要重头再来一遍(虽然后来很巧妙的解决了再来一遍的问题, 不过太“巧妙”了)。
为了实现第二个目标,gcc增加了一个与C++编译器这个身份十万八千里、莫名其妙的选项-MP。
makefile的担子很重啊~
担子重没关系,反正是计算机在做,关键是它hack,不能够忍受。
为什么不把这些事情分开做呢?
比如用一个专门的程序(就叫remove-from-project吧)来负责从记录依赖关系的makefile中去除相关的东西。
用add-to-project往makefile中添加新文件。
在具有项目管理功能的IDE中做这件事情很容易。
要在命令行做也很容易。
但问题是makefile中的东西太随心所欲了。
add-to-project和remove-from-project可以假定makefile中它需要的信息不会被改得面目全非吗?
它不能。
不光add-to-project和remove-from-project能够修改它,任何一个普通的文本编辑器都时刻准着在Eric S.  Raymond著名屁话(Being Textual)的教导下对其进行增删。
可怜的makefile,它不是
class Makefile {
public:
  void add_to_project(fname);
  void remove_from_project(fname);
private:
  ...
};
而是个人人可得而改之的
struct Makefile {
  ...
};
其实,罪不在于Being Textual(Be不Being Textual本身就是实现细节),而在于Being Textual的目的:
“让普通的文本编辑器能够编辑它们”。 


========================================================================================
后记,如今是2012--3-23了。
大概四年前(也就是我写下以上内容的时候),我被makefile给吓到了。
于是
在我还不知道scons的时候,我也尝试着用python做了个类似的东西(epm,地址:http://sourceforge.net/apps/mediawiki/epm/index.php?title=%E4%B8%AD%E6%96%87%E5%85%A5%E5%8F%A3)。这几年来,我自己的C++项目,小到到一个文件,大到数百个,都一直是用epm来管理的。当然,这只是敝帚自珍罢了,epm无论各方面跟scons都是不能比的(我当时要是知道scons,就不会有epm了)。不过,我对makefile的那段评述,大家倒是可以看看。
原创粉丝点击