Makefile规则日积月累

1."="和":="的区别

"=" makefile会将整个makefile展开后,再决定变量的值,也就是说,变量的值将会是整个makefile中最后被指定的值.

x = foo

y=$(x)bar

x=xyz

y的值是xyzbar,而不是foobar

":="表示的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。

x:=foo

y:=$(x)bar

x:=xyz

以上定义只对变量的赋值会有影响,但命令中的定义不会受影响,而是全局展开的。

查看makefile的隐藏规则:

make -p -f /dev/null |grep MAKE

获取绝对地址:

makefile的realpath返回文件的绝对地址,可以使用 $(shell pwd)来替代。

 INCLUDE的优先级:

如果任何一个通过include引入文件的被规则更新,那么makefile会接着清除它的内部数据库并重新读取整个Makefile,在完成了读取,更新,重新读取的过程后,如果仍有文件不存在而导致的include 指令执行失败,那么makefile就会报告错误并终止执行。

Makefile的静态模式%.o : %.c

Makefile的静态模式%.o : %.c_猪哥-嵌入式的博客-CSDN博客_%.o

      静态模式可以更加容易地定义多目标的规则,可以让我们的规则变得更加的有弹性和灵活  
我们还是先来看一下语法: 

<targets ...>: <target-pattern>: <prereq-patterns ...> 
<commands> 
.... 

      targets 定义了一系列的目标文件,可以有通配符。是目标的一个集合。 
      target-parrtern 是指明了 targets 的模式,也就是的目标集模式。 
      prereq-parrterns 是目标的依赖模式,它对 target-parrtern 形成的模式再进行一次依赖目标的定义。 

看一个例子: 

objects = foo.o bar.o 
 
all: $(objects) 
 
$(objects): %.o: %.c 
    $(CC) -c $(CFLAGS) $< -o $@ 

上面的例子中,指明了我们的目标从$object 中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o bar.o”,也就是变量$object 集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo bar”,并为其加下“.c”的后缀,于是,我们的依赖目标就是“foo.c bar.c”。而命令中的“$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集(也就是“foo.c bar.c”),“$@”表示目标集(也就是“foo.o bar.o”)。于是,上面的规则展开后等价于下面的规则: 
foo.o : foo.c 
$(CC) -c $(CFLAGS) foo.c -o foo.o 
bar.o : bar.c 
$(CC) -c $(CFLAGS) bar.c -o bar.o

关于$符号:

Makefile 里面 $ 是元字符(meta-chara...),也就是它是有特殊意义的。那在 Makefile 里面表示"字符" $ 就得用 $$. 看第一次求值的结果就知道了,不用多说。

有的时候$$可以代替括号,用来对多字母标识符进行引用:

解读:

第一遍,Makefile读取时候,直接对$展开,遇到 $ABC,由于 A表示符没有定义,所以展开为"  BC",输出 BC。而$(ABC),由于()的作用,ABC被识别为整体标识符,由于ABC有定义,所以展开为 "i  love you", 第三和第四种情况只查一个""符,没有本质区别,以echo $$ABC为例, $$ABC第一遍展开为$ABC,当给echo 输出的时候,再次展开的时候,变为$ABC,有定义,直接输出"i love you."

至于为何第一次 直接在makefile中echo $ABC不行,而经过$$两级展开后,变得可以,只能怀疑第三行的第一次展开是makfile系统下展开的,没有括号的情况下,$只和第一个字母配对,多字母标识符必须要加括号。而第6行则不同,它第二次是给echo看的,是echo解析的,echo 不需要加括号就可以识别整个多字母标识符号。这个过程有点像直接在bash shell中这样调用:

makefile强制更新目标:

第一步,建立空目标

PHONY += FORCE
FORCE:

第二步,将空目标作为想要强制更新的目标的依赖:

$(target): FORCE
    xxx

Makefile中获取git环境的版本ID

commid = $(shell git rev-parse HEAD)
all:
    echo $(commid)

Makefile中更新版本信息的方式:

Makefile中执行shell脚本,不在命令中的直接忽略,在命令中的执行,要写成一行,或者 \隔开。


结束

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

papaofdoudou

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

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

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

打赏作者

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

抵扣说明:

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

余额充值