Makefile学习笔记(六)

一、foreach函数

foreach函数是用来做循环的,语法规则是:

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

函数的功能就是把参数list中的单词逐个取出放在参数var所指定的变量中,然后执行text所包含的表达式。每一次text会返回一个字符串,循环过程中,text所返回的每个字符串以空格分隔,最后当整个循环结束时,text所放回的每个字符串所组成的整个字符串将会是该函数的返回值。
举例:

names := a b c d

files := $(foreach n,$(names),$(n).o)
$(names)中的单词会挨个取出,并存在变量n中,
$(n).o每次根据$(n)计算出一个值,这些值会以空格分隔,
最后作为foreach函数的返回值,所以$(files)的值是a.o  b.o    c.o  d.o

二、if函数

if函数的语法:

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

或是

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

如果condition为真,那then-part的执行结果会是整个函数的返回值,如果condition为假,那else-part的执行结果会是整个函数的返回值。

三、call函数

call函数可以给表达式传递参数。其语法是:

$(call <expression>,<parm1>,<parm2>,<parm3>...)

当make执行这个函数时,expression参数中的变量会被parm1、parm2、parm3所取代。parm参数的个数会根据expression中的变量来决定。
举例:

reverse =  $(1) $(2)

foo = $(call reverse,a,b)

所以上面代码的功能就是reverse中的变量会被a,b所取代。并且foo的值也是a,b

四、origin函数

origin函数的功能就是告诉某个参数是哪里来的。语法规则如下:

 $(origin <variable>)

variable是变量的名字,不应该是引用。所以最好不要用$这个字符,origin函数会以返回值的形式来告诉这个变量的出生情况。
下面是这个函数的一些返回值情况:

undefined
如果variable从未定义过,那么返回undefined。

default
如果variable是一个默认的变量,比如"CC"这个变量

environment
如果variable是一个环境变量,并且当makefile被执行时,“-e”参数没有被打开的情况下。

file
如果variable这个变量被定义到makefile中。

command line
如果variable这个变量是被命令行定义的。

override
如果variable这个变量是被override指示符重新定义的。

automatic
如果variable这个变量是一个在命令中运行中的自动化变量。

五、shell函数

它的参数应该就是该操作系统shell的命令,shell函数把执行操作系统命令后的输出作为函数的返回值。

contents := $(shell cat foo)

files := $(shell echo *.c)

使用shell函数要注意它是否影响运行性能,如果makefile中的规则很复杂,并且大量使用了这个函数,那么对于系统性能是有害的。

六、控制make的函数

make提供了一些函数来控制make的运行。通常,我们会根据makefile的运行信息来判断make是否继续运行。

$(error <text ...>)

text是错误信息。error函数不会再一被使用就产生错误信息,所以如果把其定义在一个变量中,并在后序的脚本里面使用这个变量,那也是行的通的。
举例:

	ifdef ERROR_001

    $(error error is $(ERROR_001))

    endif

还有这个警告函数。

$(warning <text ...>)

这个函数和error函数很像,只是它不会让make退出,只是输出一些警告信息,而继续执行make。

七、make的运行

接下来讲述怎样使用make命令。

1、make的退出码

make命令执行后有三个退出码:
0 — 表示成功执行
1 — 如果make运行时出现任何错误,其返回1
2 — 如果你使用了make的“-q”选项,并且make使得一些目标不需要更新,那么返回2

2、指定makefile

make找寻默认的makefile时,首先是在当前目录下面找“makefile”、“Makefile”、“GNUmakefile”。先查找这三个文件看存不存在,一旦找到,就开始读取这个文件并执行。
当前,我们也可以给make命令指定一个特殊名字的makefile。但是要使用make命令的-f参数或者–file参数。例如我们自己定义一个文件名叫makefiletome,那么我们就要这样执行我们的makefile:

make   -f   makefiletome

如果在make命令行中,我们不止一次使用-f参数,那么所有指定的makefile将会一起传递给make执行。

3、指定目标

一般来说,make的最终目标是makefile中的第一个目标,而其他的目标一般是被这个第一个目标连带出来的。但是,一般情况下,我们的makefile中的第一个目标会由许多目标组成,你可以指示make,让其完成所指定的目标,要实现这一功能很简单,直接在make后面跟一个目标名字就可以了。

我们可以参照这种规则来书写我们的makefile中的目标。

 “all”
    这个伪目标是所有目标的目标,其功能一般是编译所有的目标。
 “clean”
    这个伪目标功能是删除所有被make创建的文件。
 “install”
    这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去。
 “print”
    这个伪目标的功能是例出改变过的源文件。
 “tar”
    这个伪目标功能是把源程序打包备份。也就是一个tar文件。
 “dist”
    这个伪目标功能是创建一个压缩文件,一般是把tar文件压成Z文件。或是gz文件。
 “TAGS”
    这个伪目标功能是更新所有的目标,以备完整地重编译使用。
 “check”和“test”
    这两个伪目标一般用来测试makefile的流程。

这些不是硬要求,名字是可以自定义的,只不过这些名字规范些。

4、检查规则

有时,我们只是想让我们的makefile中的规则执行起来,我们只想检查一些我们的命令,或是执行的序列。于是我们可以使用make命令的下述参数

-n”
“--just-print”
“--dry-run”
“--recon”

不执行参数,这些参数只是打印命令,不管目标是否更新,把规则和连带规则下的命令打印出来,但不执行,这些参数对于我们调试makefile很有用处。

-t”
“--touch”

这个参数的意思就是把目标文件的时间更新,但不更改目标文件。也就是说,make假装编译目标,但不是真正的编译目标,只是把目标编程以编译过的状态。

-q”
“--question”

这个参数的行为就是找目标的意思,也就是说,如果目标存在,那么其什么也不会输出,当然也不会执行编译,如果目标不存在,那么将会打印一条错误信息。

-W <file>”
“--what-if=<file>”
“--assume-new=<file>”
“--new-file=<file>

这个参数需要指定一个文件,一般是源文件(或依赖文件),make会根据规则推导来运行依赖于这个文件的命令,一般来说,可以和-n参数一同使用,来查看这个依赖文件所发生的的规则命令。

5、make的参数

-B”
“--always-make”

认为所有的目标都需要更新(重编译)。

-C <dir>”
“--directory=<dir>

指定读取makefile的目录。如果有多个“-C”参数,make的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:“make –C ~hchen/test –C prog”等价于“make –C ~hchen/test/prog”。

参考资料:

https://blog.youkuaiyun.com/haoel/article/details/2896(make的运行部分)

参考资料:

https://blog.youkuaiyun.com/haoel/article/details/2895

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

思识己

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

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

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

打赏作者

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

抵扣说明:

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

余额充值