最后更新于 .

最近工作忙的要死,明明积压了一大堆博文要写,结果却始终没有时间,也沉静不下心情来写。不过知识这种东西,如果不及时沉淀下来,恐怕很容易就会忘记了,所以还是赶紧写一下。
前几天在开小组例会,同事提到了一种makefile的写法,编译过大型工程的朋友应该都知道,当多个模块要协作编译的时候,通常要进入一个个目录去编译,所以,makefile可能如下所示:

all:
    cd dir1;make all;
    cd dir3;make all;
    cd dir2;make all;
clean:
    cd dir1;make clean;
    cd dir3;make clean;
    cd dir2;make clean;

当然,我们也可以用makefile自身的特性,即 make all/clean -C dir1来进行编译,但是实际上两种写法都避免不了3个问题:
1.当新加入一个模块的时候,要写入两句代码,一句是all,一句是clean,很容易漏掉。
2.没有办法进行并行编译。因为很可能这些模块之间是不互相依赖的,而并行编译可以极大的提高速度(如果你受得了make那蜗牛般的速度的话,可以无视掉这一条)
3.依赖关系不明显(可以看出是dir2依赖与dir3,但是没有明确的指出)

那么解决方法是怎样呢?有这样一个makefile

dirs = dir1 \
       dir2 \
       dir3
.PHONY: all clean $(dirs)
all: $(dirs)
clean: $(dirs)
$(dirs):
    $(MAKE) -j2 -C $@ $(MAKECMDGOALS)
dir2:dir3

在这个makefile的同级目录有3个目录,分别为dir1,dir2,dir3,其中每个目录的makefile就不说了,大家看图应该能明白,执行make后,结果如下:

QQ截图未命名

对于并行编译的-j选项,其实我也不是很清楚,不过同事说如果cpu是多核,那么开核数+1的并行编译数是最好的,据说测试过确实如此,所以我也就没有在深究了。

另附:
    Makefile的规则:http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/make-04.html
    代码下载

Pingbacks

Pingbacks已打开。

Trackbacks

引用地址

评论

  1. zcbenz

    zcbenz on #

    既然项目庞大到需要在多个目录进行编译,为什不使用autotools?而且这样多个目录递归编译是有很大缺陷的,参见《Recursive make considered harmful》

    Reply

  2. 雨碎江南

    雨碎江南 on #

    我己经习惯在Make的时候看半个小时的书了.
    P.S.我的酷机子2GHZ的CPU,1G DDR1的内存.

    Reply

  3. bigclean

    bigclean on #

    makefile 的递归编译也试过,控制也不是太好。也可以试试其他的编译构建工具。btw,关于编译参数可以参考 gentoo 的手册,编译 gcc,openoffice 这些大件真的是耗尽了编译热情。

    Reply

  4. T.S Liu

    T.S Liu on #

    兄弟,记下了这么多东西呀!很多东西我只看过,工作中没有用到呀,你在那个那里工作,这么好的公司!!呵呵

    Reply

    1. Dante

      Dante on #

      腾讯……
      互联网公司,不得不记啊……

      Reply

  5. ivy

    ivy on #

    用Cmake挺好,又简单,又跨平台.

    Reply

发表评论