如何在Makefile中通过||忽略错误后成功修改变量值?
解决Makefile中||后无法修改变量的问题
这个问题的核心原因你可能没注意到:Makefile里的每个shell命令(包括||分隔的两端)都是在独立的子shell进程中执行的,而且你混淆了Makefile变量和shell变量的作用域——你试图在shell命令里修改Makefile变量,但shell进程的修改无法回传到Make的主上下文;就算你改的是shell变量,不同子shell之间也不共享变量。
下面给你两种针对性的解决方案,看你的需求选:
方案1:修改Makefile全局变量(后续规则可复用)
如果你需要让myVar的修改在整个Makefile中生效(比如其他规则也要用这个变量),可以用Make的$(eval)函数,它能在shell命令执行时直接修改Makefile的变量上下文:
# 初始化Makefile全局变量 myVar := "Value1" define compare_with_expect_file # 用shell的if判断diff是否失败,把所有命令放到同一个shell(用\换行) @if ! diff -c $(filePath1) $(filePath2); then \ # 用eval修改Makefile全局变量 $(eval myVar := $(myVar)$(myVar)) \ fi # 这里的echo是Make展开的myVar,已经是修改后的值 @echo $(myVar) endef # 测试规则 test: $(call compare_with_expect_file, file1.txt, file2.txt)
方案2:仅在当前命令序列中使用变量
如果只是需要在这个命令块里临时使用变量,不需要影响全局Makefile变量,那可以全程用shell变量,把所有命令放到同一个子shell中执行:
define compare_with_expect_file # 初始化shell变量,注意用$${}转义,避免Make提前展开 myVar="Value1"; \ # 判断diff结果 if ! diff -c $(filePath1) $(filePath2); then \ # 修改shell变量 myVar="$${myVar}$${myVar}"; \ fi; \ # 输出shell变量,用$$转义成shell的$ echo $$myVar endef test: $(call compare_with_expect_file, file1.txt, file2.txt)
为什么原来的代码不生效?
你原来的代码里:
myVar+=$(myVar)是在shell命令里执行的,这里的myVar是shell变量,不是你定义的Makefile变量;- 就算你修改了这个shell变量,它只存在于
||右侧的子shell中,执行完就销毁了,后面的echo $(myVar)是Make提前展开的,用的还是最初的Makefile变量值,自然看不到变化。
内容的提问来源于stack exchange,提问作者Viacheslav On
相关产品推荐
相关产品推荐

