概述
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”
最后
以上就是内向高山为你收集整理的makefile常用函数学习(wildcard foreach filter word if ) PRODUCT_COPY_FILES的全部内容,希望文章能够帮你解决makefile常用函数学习(wildcard foreach filter word if ) PRODUCT_COPY_FILES所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复