makefile常用函数学习(wildcard foreach filter word if ) PRODUCT_COPY_FILES

makefile 博大精深,看到下面一段代码,当时直接就蒙圈了.if 这个用法太怪异了,好不容易找到一个手册才理解是什么意思.整理了下相关makefile的用法,附上自己测试的例子.


这个用法主要是在android makefile里面copy配置文件用到的,例如,很多生成的sensor配置文件,由于多个项目会兼容使用,会存在多处定义,最终只会选择第一次编译运行到的定义使用. 具体定义会根据先后顺序去处掉重复的定义,只保留第一次添加到定义的文件copy对.

PRODUCT_COPY_FILES  += a: b



1.code

#####################################################
# 1 test for PRDUCT_COPY_FILE
# 2 test for basic func  foreach,eval,word,subst,info,filter
# 3 how to indicate space
######################################################

PRODUCT_COPY_FILES:=a:out/a

nullstring:= 
space :=$(nullstring) #end of the line


PRODUCT_COPY_FILES+=a:out/a


PRODUCT_COPY_FILES+=b:out/a
PRODUCT_COPY_FILES+=c:out/c

$(info #0#########copyfile end $(PRODUCT_COPY_FILES))



unique_product_copy_files_pairs :=
$(foreach cf,$(PRODUCT_COPY_FILES), \
	$(if $(filter $(unique_product_copy_files_pairs),$(cf)),,\
		$(eval unique_product_copy_files_pairs += $(cf))))


$(info #1#########copyfile end $(unique_product_copy_files_pairs))
################################################
##  func word-colon
###############################################
define word-colon
$(word $(1),$(subst :,$(space),$(2)))
endef

unique_product_copy_files_destinations	:=
$(foreach cf,$(unique_product_copy_files_pairs),	\
	$(info ++++++++++++$(cf) $(subst :,$(space),$(cf)) ++++)	\
	$(eval _src	:=$(call word-colon,1,$(cf)))	\
	$(eval _dest	:=$(call word-colon,2,$(cf)))	\
	$(info ++++++++++++$(_src)++++$(_dest)++++)	\
	$(if $(filter $(unique_product_copy_files_destinations),$(_dest)),\
		$(info PRODUCT_COPY_FILES $(cf) ignored.),\
		$(eval unique_product_copy_files_destinations+=$(_dest))))


$(info #2#########copyfile end $(unique_product_copy_files_destinations))



define func
foo:
	@echo "at foo"
endef

all:	foo main
	@echo "final"

$(eval $(call func,foo,abc.c))

main:   main.o Joseph_ring.o
	gcc -o main_new main.o Joseph_ring.o

main.o: main.c Joseph_ring.h
	gcc -c main.c

Joseph_ring.o:  Joseph_ring.c Joseph_ring.h
	gcc -c Joseph_ring.c
clean:  
	rm -f *.o main_new


2. 注解

2.1 空格表示

makefile 空格的表示方法,非常有技巧性,需要先定义一个空字符nullstring,然后定义一个新变量赋值nullstring,注意后面需要有空格,就代表一个空格,如果有两个,就代表两个空格,然后回车换行.

2.2 word-colon函数

主要作用是将字符串中的冒号替换为空格,需要注意前面空格的表示.


2.3 uniqueue_product_copy_files_pairs 

主要是去除src:dest 结构的重复字符串,主要通过if函数来完成的,通过filter过滤掉重复的字符串,条件成立则执行空,条件不成立则添加到uniqueue_product_copy_files_pairs里面


2.4 unique_product_copy_files_destinations

通过word-colon提取出_dest字符串,然后通过filter过滤掉重复的字符串,条件成立则提醒已存在对应字符串,忽略掉对应的字符串,不成立的话添加到unique_product_copy_files_destinations里面.

因此android里面的PRODUCT_COPY_FILES变量就是会对敌一个字符串进行添加,后面的就会不起作用.如果需要使自己的文件生效就需要尽量把自己定义的copy文件放在最前面赋值才能生效.


3.常用函数

makefile 里的函数跟它的变量很相似——使用的时候,你用一个 $ 符号跟开括号,函数名,空格后跟一列由逗号分隔的参数,最后 用关括号结束。
例如,在 GNU Make 里有一个叫 'wildcard' 的函 数,它有一个参数,功能是展开成一列所有符合由其参数描述的文 件名,文件间以空格间隔。
你可以像下面所示使用这个命令: 
     
    SOURCES = $(wildcard *.c) 
     
    这行会产生一个所有以 '.c' 结尾的文件的列表,然后存入变量 SOURCES 里。当然你不需要一定要把结果存入一个变量。 
    另一个有用的函数是 patsubst ( patten substitude, 匹配替 换的缩写)函数。它需要3个参数——第一个是一个需要匹配的式样,
第二个表示用什么来替换它,第三个是一个需要被处理的 由空格分隔的字列。例如,处理那个经过上面定义后的变量, 
     
    OBJS = $(patsubst %.c,%.o,$(SOURCES)) 
     
    这行将处理所有在 SOURCES 字列中的字(一列文件名),如果它的 结尾是 '.c' ,就用 '.o' 把 '.c' 取代。
注意这里的 % 符号将匹 配一个或多个字符,而它每次所匹配的字串叫做一个‘柄’(stem) 。 在第二个参数里, % 被解读成用第一参数所匹配的那个柄。




 $(foreach <var>;,<list>;,<text>;) 


这个函数的意思是,把参数<list>;中的单词逐一取出放到参数<var>;所指定的变量中,然后再执行<text>;所包含的表达式。
每一次<text>;会返回一个字符串,循环过程中,<text>;的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>;
所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。


$(filter PATTERN…,TEXT) 
函数名称:过滤函数—filter。 
函数功能:过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,保留所
有符合此模式的单词。可以使用多个模式。模式中一般需要包含模式字
符“%”。存在多个模式时,模式表达式之间使用空格分割。 
返回值:空格分割的“TEXT”字串中所有符合模式“PATTERN”的字串。 
函数说明:“filter”函数可以用来去除一个变量中的某些字符串,我们下边的例子中
就是用到了此函数。 
示例: 
sources := foo.c bar.c baz.s ugh.h 
foo: $(sources) 
cc $(filter %.c %.s,$(sources)) -o foo 
 
使用“$(filter %.c %.s,$(sources))”的返回值给 cc 来编译生成目标“foo”,函数返回
值为“foo.c bar.c baz.s”


***************************************************
这里的if是个函数, 和前面的条件判断不一样, 前面的条件判断属于Makefile的关键字


语法:


$(if <condition>,<then-part>)


$(if <condition>,<then-part>,<else-part>)



$(word N,TEXT) 
函数名称:取单词函数—word。 
函数功能:取字串“TEXT”中第“N”个单词(“N”的值从 1开始)。 
返回值:返回字串“TEXT”中第“N”个单词。 
函数说明:如果“N”值大于字串“TEXT”中单词的数目,返回空字符串。如果“N”
为 0,出错! 
示例: 
$(word 2, foo bar baz) 
返回值为“bar”

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

newtonnl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值