makefile 打印变量_[Makefile] 缩进与空格--记录踩过的坑

今天折腾了好久,就为了debug两个makefile的bug。虽然最后找到原因了,但是,怎么说呢,用现在流行的话来说,实在是意难平啊!必须写一篇记录一下!

第一个问题,是个语法高亮问题。今天观察到makefile里一些有缩进的语句,没有被正确的语法高亮,比如下面这样:

d3e81792b60d3dc18d33d7d6ea78e72d.png
看起来没什么毛病……就是变量B怎么不给我高亮?

而正常来说,B应该被识别成变量:

464f1809907722d19780beb276b4ae98.png
正常来说B应该被识别成变量

问题的原因是在写非recipe的时候,缩进应该使用空格而非TAB。在写makefile中的recipe时,因为实际上我们写的是希望shell执行的语句,所以使用的是shell syntax。而make识别recipe的方式就是缩进使用TAB。而其他时候,比如上面的例子中,我们并非在写recipe,这时候syntax应该按照makefile风格来写,所以应当使用空格来缩进。这也正是编辑器对语法高亮识别的方式。

虽然看起来只是语法高亮的问题,但归根结底是make如何识别makefile中语句的问题。错误的缩进可能导致其他问题,比如在下面的例子中:

A

我们的本意是打印B的值,但是执行结果却是打印了一个空行,同时接着一行B=B。这背后的原因,就是B=B这一行使用了TAB来缩进,因此make把这一行也当做recipe的一部分,于是将其交给Shell执行。而除此之外,makefile中没有定义B的值,因此echo打印了一个空行,并且B=B也被打印出来。

d4b1f3d6501b67e851f94c0d2bebdb55.png
Wrong !

可以参考GNU Make 5.1节深入学习recipe syntax问题。

第二个问题看起来就更奇怪一些。出错的代码类似下面这样:

A

看起来打印的结果应该是B,但实际上执行的结果却打印了C:

a962ae41fd93745ad6f2c6673d59ff55.png

3c4dde13a063728ec003e03c7491362b.png

这个问题表面上看非常不可思议。而真正发现问题之后,也让人不禁摇头感叹。这个问题其实上仅仅因为A=A这一行的结尾多了一个空格。所以变量A实际上值是"A "。故而ifeq语句走了else分支。

这种问题知道之后觉得是个非常郁闷,但makefile似乎很难避免这样的问题。因为在makefile中,语句之间没有分隔符号,同时对字符串变量也不需要加引号。在我们日常使用的很多语言中,空格是可以自由添加的,本身不代表任何含义。所以习惯了其他语言语法的我们,面对这种"ghost white space"真的很难发现。我们只能要求维护makefile的同事多留心了。

另外,对于变量来说,实际上=前后是允许有空格的,并且会被忽略掉,不会当做值的一部分。但行尾的空格则相反。

希望以后都不要再debug makefile问题了……愿这篇文章没有更新……

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值