1 "="和":="
"="号赋值时,如果右边的值里面有未展开的变量,要等到整个Makefile的变量处理完之后,再展开,也就是说,如果该未被展开的变量的值在
该赋值后面被修改了,那么最后会赋值为修改之后的值。
":="号赋值时,未被展开的变量的赋值时立即被展开然后赋值的。就算后面修改了,也对本变量没有影响。
前者是deferred,后者是immediately。
2 .c.o:
是老式的写法,等价于%.o : %.c
这个称为double suffix rule,.c.o只是一个例子,还有.c.lo,.c.obj等等。
3 关于make中的模式
普通的文件名,普通的变量名也是一种pattern,不一定有通配符正则表达式才是pattern,这种pattern只是能够匹配一个结果而已。
4 什么时候使用$$xxx,即连续使用两个$
分三种情况:
4.1 $$变量名
定义在recipe中的变量,即shell变量,而不是make变量,要用$$+变量名来引用。这样,shell变量和make变量不会发生冲突。
4.2 $$用于avoid expansion
比如echo 'builddir=`dirname "$$0"`',本来在执行这条命令前,make会对$0进行expansion,但是这里加了一个$,就不会expansion了,直接使用$0,会丢掉一个$,就相当于前面的$替后面的$挡了一箭。
这个向文件中写入命令时最常用。
4.3 在bash shell的命令扩展前加上一个$
这个也是作为后面一个$的挡箭牌,这样,执行命令之前,make进行变量扩展之后,就能够保持bash shell的命令行扩展命令本身,会丢掉一个$。
否则,会当成是make的builtin的扩展了。
比如$$(basename xxx),就是linux命令basename,是bash的command expansion,否则就是$(basename xxx),是make的builtin basename的扩展了。