分类: C/C++
2012-12-17 10:23:34
要对子目录执行make,需要在当前目录制作一个Makefile,遍历所有子目录的Makefile,并运行相应的make target.
#
# Reference
#
# 需要排除的目录
exclude_dirs := include bin
# 取得当前子目录深度为1的所有目录名称
dirs := $(shell find . -maxdepth 1 -type d)
dirs := $(basename $(patsubst ./%,%,$(dirs)))
dirs := $(filter-out $(exclude_dirs),$(dirs))
# 避免clean子目录操作同名,加上_clean_前缀
SUBDIRS := $(dirs)
clean_dirs := $(addprefix _clean_,$(SUBDIRS) )
#
.PHONY: subdirs $(SUBDIRS) clean
# 执行默认make target
$(SUBDIRS):
$(MAKE) -C $@
subdirs: $(SUBDIRS)
# 执行clean
$(clean_dirs):
$(MAKE) -C $(patsubst _clean_%,%,$@) clean
clean: $(clean_dirs)
@find . \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.symtypes' \) \
-type f -print | xargs rm -f
本文转自:http://langhuazht.blog.163.com/blog/static/1061055122009021105014565/
目的: 得到指定路径下源文件名称集合
依次循环取得各目录下的所有源文件,在各目录下取源文件时过滤不支持的源文件格式,
得到源文件集合(带路径)
SOURCES := $(foreach x,${SRC_DIR},\
$(wildcard \
$(addprefix ${x}/*,${SFIX}) ) )
例:
OS = ./plus --------------------------------- .c文件所在目录
OS_C := $(foreach x,${OS},\ ----------------得到该目录下所有的 .c 文件
$(wildcard \
$(addprefix ${x}/*,.c) ) )
解释以下makefile中的函数:
1、foreach:
foreach是用来做循环用的,类似于for 语句,语法是:$(foreach ,,
意思:把参数中的单词逐一取出放到参数所指定的变量中,然后再执行
可以是一个表达式,而
中的单词。
例:
names := a b c d
files := $(foreach n,$(names),$(n).o)
$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。
2、wildcard:
使用wildcard得到指定目录下所有的C语言源程序文件名的方法,不用手工一个一个指定需要编译的.c文件了,方法如下:
SRC = $(wildcard *.c)
等于指定编译当前目录下所有.c文件,如果还有子目录,比如子目录为inc,则再增加一个wildcard函数:
SRC = $(wildcard *.c) $(wildcard inc/*.c)
也可以指定汇编源程序:
ASRC = $(wildcard *.S)
3、addprefix:
1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符
例子:
建立一个测试目录,在测试目录下建立一个名为sub的子目录
$ mkdir test
$ cd test
$ mkdir sub
在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件
建立一个简单的makefile
src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )
all:
@echo $(src)
@echo $(dir)
@echo $(obj)
@echo "end"
执行结果分析:
第一行输出:
a.c b.c ./sub/sa.c ./sub/sb.c
wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。
第二行输出:
a.c b.c sa.c sb.c
notdir把展开的文件去除掉路径信息
第三行输出:
a.o b.o sa.o sb.o
在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o,
任何输出。
或者可以使用
obj=$(dir:%.c=%.o)
效果也是一样的。
这里用到makefile里的替换引用规则,即用您指定的变量替换另一个变量。
它的标准格式是
$(var:a=b) 或 ${var:a=b}
它的含义是把变量var中的每一个值结尾用b替换掉a