Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1540962
  • 博文数量: 273
  • 博客积分: 2366
  • 博客等级: 大尉
  • 技术积分: 1875
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-22 09:37
文章分类

全部博文(273)

文章存档

2020年(10)

2019年(7)

2018年(18)

2017年(26)

2016年(32)

2015年(43)

2014年(30)

2013年(44)

2012年(36)

2011年(17)

2010年(10)

分类: C/C++

2012-12-17 10:23:34

一个遍历当前子目录的Makefile模板

要对子目录执行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 ,, )
       意思:把参数中的单词逐一取出放到参数所指定的变量中,然后再执行所包含的表达式。每一次会返回一个字符串,循环过程中,的所返回的每个字符串会以空格分隔,最后当整个循环结束时,所返回的每个字符串所组成的整个字符串(以空格分隔)将会是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:    

     功能:$(addprefix , )   ,加前缀函数,把前缀加到中的每个单词前。
     返回:返回加过前缀的文件名序列。
     例:$(addprefix src/,foo bar)返回值是“src/foo src/bar”。


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 

阅读(1536) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~