Makefile常用函数的整理

函数调用的格式如下:

$(function arguments)

这里function’ 是函数名,arguments’ 是该函数的参数。参数和函数名之间是用空格
或 Tab 隔开,如果有多个参数,它们之间用逗号隔开。这些空格和逗号不是参数值的一部分。
内核的 Makefile 中用到大量的函数,现在介绍一些常用的。

字符串替换和分析函数

  • ( 1) $(subst from,to,text)

在文本text’中使用to’替换每一处from’。
比如: $(subst ee,EE,feet on the street)
结果为‘ fEEt on the street’。

  • ( 2) $(patsubst pattern,replacement,text)

寻找ext中符合格式pattern的字,用replacement替换它们。 pattern和
replacement中可以使用通配符。
比如: $(patsubst %.c,%.o,x.c.c bar.c)
结果为:`x.c.o bar.o’ 。

  • 3) $(strip string)

去掉前导和结尾空格,并将中间的多个空格压缩为单个空格。
比如: $(strip a b c )
结果为`a b c’ 。

  • ( 4) $(findstring find,in)

在字符串n中搜寻find ,如果找到,则返回值是find ,否则返回值为空。
比如: $(findstring a,a b c)
$(findstring a,b c)
将分别产生值a 和`’ (空字符串)。

  • ( 5) $(filter pattern…,text)

返 回 在 text’中 由 空 格 隔 开 且 匹 配 格 式 pattern…的 字 , 去 除 不 符 合 格 式
pattern…的字。 比如: $(filter %.c %.s,foo.c bar.c baz.s ugh.h)
结果为`foo.c bar.c baz.s’。

  • ( 6) $(filter-out pattern…,text)

返 回 在 text中 由 空 格 隔 开 且 不 匹 配 格 式 pattern…的 字 , 去 除 符 合 格 式
pattern… 的字。 它是函数 filter 的反函数。
比如: $(filter %.c %.s,foo.c bar.c baz.s ugh.h)
结果为`ugh.h’ 。

  • ( 7) $(sort list)

将‘ list’中的字按字母顺序排序,并去掉重复的字。输出由单个空格隔开的字的列表。
比如: $(sort foo bar lose)
返回值是‘ bar foo lose’

2. 文件名函数

  • ( 1) $(dir names…)

抽取‘ names…’中每一个文件名的路径部分,文件名的路径部分包括从文件名的首字 符到最后一个斜杠(含斜杠)之前的一切字符。
比如:$(dir src/foo.c hacks)
结果为‘src/ ./’ 。

  • ( 2) $(notdir names…)

抽取‘ names…’中每一个文件名中除路径部分外一切字符(真正的文件名)。
比如: $(notdir src/foo.c hacks)
结果为‘ foo.c hacks’ 。

  • ( 3) $(suffix names…)

抽取‘ names…’中每一个文件名的后缀。
比如: $(suffix src/foo.c src-1.0/bar.c hacks)
结果为‘ .c .c’ 。

  • ( 4) $(basename names…)

抽取‘ names…’中每一个文件名中除后缀外一切字符。
比如: $(basename src/foo.c src-1.0/bar hacks)
结果为‘ src/foo src-1.0/bar hacks’ 。

  • ( 5) $(addsuffix suffix,names…)

参数‘ names…’ 是一系列的文件名,文件名之间用空格隔开; suffix 是一个后缀名。 将
suffix(后缀)的值附加在每一个独立文件名的后面,完成后将文件名串联起来,它们之间 用单个空格隔开。
比如: $(addsuffix .c,foo bar)
结果为‘ foo.c bar.c’

  • ( 6) $(addprefix prefix,names…)

参数‘ names’ 是一系列的文件名,文件名之间用空格隔开; prefix 是一个前缀名。将
preffix(前缀)的值附加在每一个独立文件名的前面,完成后将文件名串联起来,它们之间用 单个空格隔开。
比如: $(addprefix src/,foo bar)
结果为‘ src/foo src/bar’ 。

  • ( 7) $(wildcard pattern)

参数‘ pattern’是一个文件名格式,包含有通配符(通配符和 shell 中的用法一样)。函 数 wildcard
的结果是一列和格式匹配的且真实存在的文件的名称,文件名之间用一个空格隔 开。
比如若当前目录下有文件 1.c、 2.c、 1.h、2.h,
则: c_src := $(wildcard *.c) 结果为‘ 1.c 2.c’ 。

3. 其他函数

  • ( 1) $(foreach var,list,text)

前两个参数,‘ var’和‘list’将首先扩展,注意最后一个参数‘ text’此时不扩展; 接着,‘ list’扩展所得的每个字,都赋给‘ var’变量;然后‘ text’引用该变量进行扩展, 因此‘ text’ 每次扩展都不相同。 函数的结果是由空格隔开的‘text’ 在‘ list’中多次扩展后,得到的新‘ list’ ,就 是说: ‘text’多次扩展的字串联起来,字与字之间由空格隔开,如此就产生了函数 foreach 的返回值。
下面是一个简单的例子,
将变量‘files’ 的值设置为 ‘dirs’ 中的所有目录下的所有 文件的列表:
dirs := a b c d files := ( f o r e a c h d i r , (foreach dir, (foreachdir,(dirs),$(wildcard $(dir)/*))

这里 text是$(wildcard $$(dir)/*) ,它的扩展过程如下

① 第一个赋给变量 dir 的值是a’ 扩展结果为$(wildcard a/*)

② 第二个赋给变量 dir 的值是b, 扩展结果为$(wildcard b/*)

③ 第三个赋给变量 dir 的值是c,扩展结果为$(wildcard c/*)
④ 如此继续扩展。 这个例子和下面的例有共同的结果

files :=$(wildcard a/* b/* c/* d/*)

  • ( 2) $(if condition,then-part[,else-part])

首先把第一个参数‘ condition’ 的前导空格、结尾空格去掉,然后扩展。如果扩展为非 空字符串,则条件‘condition’为‘真’;如果扩展为空字符串,则条件‘ condition’为‘假’。 如果条件‘ condition’为‘真’,那么计算第二个参数‘ then-part’的值,并将该值作 为整个函数 if 的值。 如果条件‘ condition’为‘假’,并且第三个参数存在,则计算第三个参数‘ else-part’ 的值,并将该值作为整个函数 if 的值;如果第三个参数不存在,函数 if将什么也不计算, 返回空值。 注意: 仅能计算‘ then-part’和‘ else-part’二者之一,不能同时计算。这样有可能产生 副作用(例如函数 shell 的调用)。

  • ( 3) $(origin variable)

变量‘ variable’是一个查询变量的名称,不是对该变量的引用。所以,不能采用‘ $’ 和圆括号的格式书写该变量,当然,如果需要使用非常量的文件名,可以在文件名中使用变 量引用。第 4 章 嵌入式编程 函数 origin的结果是一个字符串,该字符串变量是这样定义的: ‘ undefined’ :如果变量‘ variable’ 从没有定义; ‘ default’ :变量‘ variable’ 是缺省定义; ‘ environment’ :变量‘ variable’作为环境变量定义,选项‘ -e’ 没有打开; ‘ environment override’ :变量‘ variable’ 作为环境变量定义,选项‘ -e’ 已打开; ‘ file’ :变量‘ variable’ 在 Makefile 中定义; ‘ command line’ :变量‘ variable’ 在命令行中定义; ‘ override’ :变量‘ variable’ 在 Makefile 中用 override 指令定义; ‘ automatic’ :变量‘ variable’ 是自动变量

  • ( 4) $(shell command arguments)

函数 shell 是 make 与外部环境的通讯工具。函数 shell 的执行结果和在控制台上执行 ‘ command arguments’的结果相似。不过如果‘ command arguments’的结果含有换行符(和 回车符),则在函数 shell 的返回结果中将把它们处理为单个空格,若返回结果最后是换行符 (和回车符)则被去掉。
比如当前目录下有文件 1.c、 2.c、 1.h、2.h,
则: c_src := $(shell ls *.c) 结果为‘ 1.c 2.c’ 。

例子:

Makefile

src := $(shell ls *.c)
objs := $(patsubst %.c, %.o, $(src))

test:$(objs)
        gcc -o $@ $^

%.o:%.c
        gcc -c -o $@ $<

上述 Makefile 中$@、 $^、 $<称为自动变量。 $@表示规则的目标文件名; $^表示所有依赖
的名字,名字之间用空格隔开; $<表示第一个依赖的文件名。‘ %’是通配符,它和一个字符
串中任意个数的字符相匹配。

a.c

#include<stdio.h>
  
extern int fun1(int i);

int main()
{
        int ret = 0;
        ret = fun1(3);
        printf("main ret = %d\n", ret);
        return ret;
}

b.c

#include<stdio.h>
extern int fun2(int i);
int fun1(int i)
{
        printf("fun1 rx %d\n", i);
        return fun2(i);

d.c

#include<stdio.h>

int fun2(int i)
{
        printf("fun2 rx %d\n", i);
        return i+3;
}

执行make

kayshi@ubuntu:~/code/makefile$ make
gcc -c -o a.o a.c
gcc -c -o b.o b.c
gcc -c -o d.o d.c
gcc -o test a.o b.o d.o
kayshi@ubuntu:~/code/makefile$ ls
a.c  a.o  b.c  b.o  d.c  d.o  Makefile  test
kayshi@ubuntu:~/code/makefile$ ./test 
fun1 rx 3
fun2 rx 3
main ret = 6

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值