Makefile的嵌套调用

来源:互联网 发布:淘宝经常退款会怎么样 编辑:程序博客网 时间:2024/06/06 00:55

Makefile的嵌套调用

Content

  • Makefile的嵌套调用
    • Content
    • 问题介绍
    • 解决方法一
    • 问题再发现
    • 解决方法二
    • 参考


问题介绍

  现有子文件夹A和B,A、B中均有已经可以正常编译的代码以及Makefile,现要在文件夹中利用Makefile调用各个子目录中的Makefile,完成各个文件夹的编译。文件树如下:
eli@eli:~$ tree makemake├── A│   ├── a.cpp│   └── Makefile└── B    ├── b.cpp    └── Makefile2 directories, 4 files

解决方法一

make的选项-C的作用是,执行前切换到相应的目录,再执行make,完成后退回到原始的目录,因此可以使用这一方法解决这一问题。相应的Makefile为:
#get all the subdir                                                                                                                        SUBDIRS = $(shell ls -l | grep ^d | awk '{print $$9}')all:$(SUBDIRS)    $(SUBDIRS):ECHO    make -C $@ allECHO:    @echo $(SUBDIRS)

问题再发现

Makefile的功能应当不止于编译,一般而言还应当具有install和clean的功能。但是,如果以上一种方法,我们为每一个目录名称创建了一个规则,如果再在install或者clean的目标下使用相同的方法,那么会产生规则重复的问题
Makefile:22: warning: overriding recipe for target 'A'Makefile:14: warning: ignoring old recipe for target 'A'Makefile:22: warning: overriding recipe for target 'B'Makefile:14: warning: ignoring old recipe for target 'B'

因此,我们需要采用新的方法,可以使用shell语言中的for语句来完成,这里假设我们需要将编译好的程序复制到tools目录下。

解决方法二

#get all the subdir except the install dir                                                                                                 SUB_DIR = $(shell ls -l | grep ^d |awk '{if($$9 != "tools") print $$9}')INSTALL_DIR = tools#save the root dirROOT_DIR = $(shell pwd)#export dirs so the Makefile in the subdirs can use themexport ROOT_DIR INSTALL_DIRall:    for dir in $(SUB_DIR); do \        make -C $$dir; \    doneinstall:    for dir in $(SUB_DIR); do \        make -C $$dir install; \    done
clean目标也可以使用for语句实现。最后的结果是:
make/├── A│   ├── A│   ├── a.cpp│   ├── a.o│   └── Makefile├── B│   ├── B│   ├── b.cpp│   ├── b.o│   └── Makefile├── Makefile└── tools    ├── A    └── B3 directories, 11 files

参考

  1. 多文件目录下makefile文件递归执行编译所有c文件
  2. Run make in each subdirectory

备注
刚刚接触Makefile和shell不久,因此也不知道有没有更好的实现方法,希望多多交流.