Makefile重修班

前几天一直在研究boost的spirit库。很强大也很难使用,根本没有轻量级的特点。转而研究lex/yacc。

但是在给lex/yacc写Makefile的时候出了点问题。

%.yy.o : %.yy.c %.tab.h
        $(CC) -c -o $@ $*.yy.c

%.yy.c : %.l
        $(LEX) -o $@ $<

%.tab.c %.tab.h : %.y
        $(YACC) -d -o $*.tab.c $<

后两个规则把lex和yacc文件编译成对应的.yy.c、.tab.c和.tab.h。第一个规则是确保在编译.yy.c之前,先得到对应的.tab.h文件。

保存,make,bin文件一切正常。但是.yy.c和.tab.h却不翼而飞。煮熟的鸭子要飞走……

重新读了一下陈皓那本跟我一起学写Makefile关于隐含规则的一章。原来这种由隐含规则链生成的中间文件默认是会被rm -f删除的。如果不想删除这些中间文件,应该加上一行告诉make它们是珍贵的:

.PRECIOUS: %.yy.c %.tab.c %.tab.h

不过这样做通常并无必要,因为位于隐含规则链中间的文件最后修改时间是无关紧要的,只要链的源头新于链的目标,在任何时候整条链都需要重新编译。及时保存了中间文件也不可能让编译从中间开始。当然,如果可能需要手动修改中间文件,这样做也许是必要的。

on December 13th, 2008 | No Comments »

Boost库文件文件名完全解析

今天总算完全弄明白了编译boost文件名前缀和后缀的含义。

在Windows上完整的编译boost大约会生成4GB左右的库文件。总的来说有如下分类:

  1. st和mt,分别对应单线程和多线程。如果你在使用Visual Studio .Net 2005及以上的版本。请直接删除st系列,因为KB154753中提到,The /ML and /MLd library compiler options for static single-threaded libraries were removed in Visual C++ 2005 and in later versions of Visual C++. 令人奇怪的是编译boost的时候它们是怎么跑出来的,在编译器都抛弃它们的情况下…
  2. 带gd和不带gd的,这个大家都知道,分别是debug和release。
  3. 带s和不带s的,s当然是指static,但并不是用于static链接,而是指是否已经把runtime library静态链接,参见这里
  4. 以libboost开头和以boost开头的,前者是静态链接用的,后者是动态链接用的。动态链接版本的包括一个链接时需要的lib文件和一个运行时需要的dll文件;而静态链接版本的就只有一个lib文件。
  5. 带版本号和不带版本号的,这两种完全一样,都是Windows没有符号链接的错。建议保留版本号。

通常情况下只需要动态链接的库文件即可,mt和mt+gd,大约25MB而已。但记得定义BOOST_ALL_DYN_LINK宏,否则boost的自动链接指令默认的是静态库。

ps. 不小心把文章删掉了,从Google Reader里面重新找了出来。

ps. 增加一条:后缀带p的是指使用STLport编译的。

on November 18th, 2008 | 1 Comment »