学习自狄泰软件学院唐佐临老师Makefile课程,文章中图片取自老师的PPT,仅用于个人笔记。
实验1 : 自定义函数调用实例
实验2 :自定义函数调用深度理解1
实验3 :自定义函数调用深度理解2
实验4 :call 处理的对象是多行变量
实验5:调用 预定义函数
/*
$(0) : 代表 第0号参数 是 自定义函数名字
*/
define func1
@echo "My name is $(0),"
endif
/*
$(0) : 代表 第0号参数 是 自定义函数名字
$(1) : 代表 第1号参数 是 当前函数在调用的时候第一个实参的值
*/
define func2
@echo "My name is $(0),"
@ehco "Param => $(1)"
endif
调用形式:
test :
$(call func1) // 通过 call 调用自定义函数func1
$(call func2,D.T.Software) //通过 call 调用自定义函数func2,后面是第一号实参。
实验1 : 自定义函数调用实例
.PHONY : test
define func1
@echo "My name is $(0)"
endef
define func2
@echo "My name is $(0)"
@echo "Param 1 => $(1)"
@echo "Param 2 => $(2)"
endef
test :
$(call func1) #在规则中调用 func1
$(call func2, D.T.Software, delphi_tang) #在规则中调用 func2
mhr@ubuntu:~/work/makefile1$ make
My name is func1
My name is func2
Param 1 => D.T.Software
Param 2 => delphi_tang
mhr@ubuntu:~/work/makefile1$
实验2 :自定义函数调用深度理解1
.PHONY : test
define func1
@echo "My name is $(0)"
endef
# 调用 func1 初始化 变量var,可以这样操作吗?并没有在规则中调用,func1 调用成功了吗?
# 肯定是不会成功的,自定义函数调用必须在规则中使用,如例1
var := $(call func1)
test :
@echo "var => $(var)"
// 函数没有被调用,这里打印的是 func1这个多行变量的值: @echo "My name is $(0)"
// 如果是 函数调用 打印的应该是 :My name is func1
mhr@ubuntu:~/work/makefile1$
mhr@ubuntu:~/work/makefile1$ make
var => @echo My name is func1
mhr@ubuntu:~/work/makefile1$
说明:实验结果打印了
var => @echo My name is func1
函数被调用了吗? 函数肯定没有被调用,这仅仅是 func1这个多行变量的值。define 是用来定义多行变量的,只不过说 多行变量可以在call 的作用下当作一个自定义函数来使用,这个使用又是有限制的,必须在规则中使用,所以这个位置 这样写 :
var := $(call func1)
是不会起到函数调用的作用的,这样写仅仅是把 func1 当做一个变量来处理了。自定义函数的本质就是多行变量。
实验3 :自定义函数调用深度理解2
.PHONY : test
define func1
@echo "My name is $(0)"
endef
new := $(func1)
test :
@echo "new => $(new)"
mhr@ubuntu:~/work/makefile1$ make
new => @echo My name is
mhr@ubuntu:~/work/makefile1$
说明:打印出来 new 的值没有函数名,所以 对比上一个实验可以知道,call 的作用就是将实参替换到函数体当中对应的位置。如 new := $(func1) ,并没有使用call,所以说并不会将这个变量里面的相应位置的地方换成实参。
结论
结论:在 makefile里面,其实是使用多行变量来模拟自定义函数,所谓定义的自定义函数 并不是定义了函数,而是定义了多行变量,只不过说我们使用call ,在 call 的作用下,可以将实参的值替换到多行变量的对应位置。call 的作用就是将实参替换到函数体当中对应的位置。通过前两个例子,可以知道,为什么自定义函数只能用于规则中才有函数意义并且只能用于定义命令的集合了,就是因为 命令只能在规则中被执行,在其他地方调用 多行变量 只是打印命令本身,有call 的话会替换一下实参。本身就是为了方便的在规则中调用一系列命令。
自定义函数就是 call 这个预定义函数的实参,并且在call这个预定义函数内部被执行,其实就是参数的替换,替换之后得到的就是一系列 命令集合,既然是命令的集合,也就只能在规则中真正的执行了。
实验4 :call 处理的对象是多行变量
.PHONY : test
define func1
@echo "My name is $(0)"
endef
# 不是多行变量
func2 := @echo "My name is $(0)"
test :
$(call func1)
$(call func2)#call 处理的是多行变量,这里的func2 并非是多行变量,不能正常工作 不传参
mhr@ubuntu:~/work/makefile1$
mhr@ubuntu:~/work/makefile1$ make
My name is func1
My name is
mhr@ubuntu:~/work/makefile1$
实验5:调用 预定义函数
.PHONY : test
define func1
@echo "My name is $(0)"
endef
define func2
@echo "My name is $(0)"
endef
#调用 预定义函数
var1 := $(call func1)
var2 := $(call func2)
var3 := $(abspath ./) #当前 目录绝对路径
var4 := $(abspath test.cpp) # 当前目录下 cpp 文件的绝对路径
test :
@echo "var1 => $(var1)"
@echo "var2 => $(var2)"
@echo "var3 => $(var3)"
@echo "var4 => $(var4)"
mhr@ubuntu:~/work/makefile1$
mhr@ubuntu:~/work/makefile1$ make
var1 => @echo My name is func1
var2 => @echo My name is func2
var3 => /home/mhr/work/makefile1
var4 => /home/mhr/work/makefile1/test.cpp
mhr@ubuntu:~/work/makefile1$
解析:
/*
var1 := $(call func1)
var2 := $(call func2)
本质是调用了 call 函数,call 函数的内部用来处理 func1 func2这两个多行变量具体的
值,就是将call 的参数替换到多行变量相对应的位置
*/
var1 => @echo My name is func1
var2 => @echo My name is func2