Makefile同一行重复使用同一变量失效问题求助
解决Boilermake模板中Recipe参数重复展开丢失的问题
嘿,我刚好碰到过类似的Makefile参数展开坑,尤其是用Boilermake这种模板的时候,给你捋清楚怎么解决:
问题到底出在哪?
你遇到的核心问题是Makefile的变量展开时机。当你用define定义recipe时,直接写$(1)的话,Make在解析这个recipe定义的阶段就会尝试立即展开$(1)——但这时候$(1)还没被传入具体值,等你用call调用时,第二次出现的$(1)已经被空值覆盖了,所以就只剩下.bin了。
直接能用的解决方案
你只需要在定义recipe时,把参数$(1)改成$$(1)(双重美元符号),延迟参数的展开时机,这样每次调用时两个位置的参数都会被正确替换。
正确的Recipe定义
define build_binary objcopy $$(1).elf -O binary $$(1).bin endef
调用方式不变
当你需要生成某个目标时,直接用call传入参数就行:
$(call build_binary, myapp)
执行后会生成正确的命令:
objcopy myapp.elf -O binary myapp.bin
为啥双重美元符号管用?
在Makefile里,单个$是用来即时展开变量/参数的,而$$会被Make解析成一个普通的$存进recipe的定义里。当你用call调用这个recipe时,Make会重新扫描整个命令,把$(1)替换成你传入的实际参数——这样两个$$(1)就都会被正确替换成myapp(或者你传入的任何值)。
额外要检查的小细节
如果上面的方法还是没生效,你可以排查这两点:
- 看看Boilermake模板有没有对参数做特殊封装:有些模板会把参数放进变量里,这时候可能需要用模板指定的参数格式,比如
$(1_NAME)之类的(不过Boilermake一般还是标准的$(1))。 - 调用时别给参数加引号:比如
$(call build_binary, "myapp")会生成"myapp".elf,这肯定不是你想要的,直接传裸参数就好。
内容的提问来源于stack exchange,提问作者filo
相关产品推荐
相关产品推荐

