显然GNU Make条件中没有布尔类型,所以这似乎是最好的解决方案:
$(DEF_TARGET):
if [ "$(CHECK)" != "y" ]; then \
var=foo; \
$(if $(filter foo,$(var)),result=true,result=false); \
fi
问题在于,无论var=foo
还是var=bar
,result
始终是false
。用$(var)
或foo
替换bar
会产生正确的结果。
为什么这不起作用?有没有更好的解决方案?
修改
使用命令make -f make.txt
.PHONY: all
all:
X=aaa; \
Y=aaa; \
if [[ '$(filter $(X),$(Y))' ]]; then echo "matched!"; else echo "not matched!"; fi
输出:
X=aaa; \
Y=aaa; \
if [[ '' ]]; then echo "matched!"; else echo "not matched!"; fi
not matched!
为目标配方中的X
和Y
分配值时,为什么会失败?
答案 0 :(得分:3)
显然GNU Make条件
中没有布尔类型
显然there is,否则$(if ...)
宏的存在就没有意义了!
阅读食谱的方法 (即构建目标的shell命令块) 应理解 make 将配方存储为单个递归扩展变量。 仅当 make 需要将一些命令传递给shell时,才会扩展配方。
配方整体扩展一次。 然后逐个执行所得到的扩展的每一行。 每次执行都在shell的 new 实例中运行。
所以,
拿你原来的makefile,
我们假设你已经要求 make 来构建${DEF_TARGET}
。
制作扩展食谱:
if [ "$(CHECK)" != "y" ]; then \ var=foo; \ $(if $(filter foo,$(var)),result=true,result=false); \ fi
${CHECK}
变得一无所知(比如说) $(if $(filter foo,$(var)),result=true,result=false)
${var}
已展开,也变为空(比如说)。
请注意,配方中的行var=foo
是不由make解释!
这是一个shell命令。$(filter foo,)
展开,也是空的。下一步 make 展开$(if ,result=true,result=false)
,当然会产生result=false
。
if [ "" != "y" ]; then \
var=foo; \
result=false; \
fi
由于反斜杠,Make 将此视为一行。
所以, 不要混淆shell变量和 make 变量。 在shell获取配方时,所有 make 变量都消失了。 Make 对shell变量一无所知。
您的原始shell代码段可能类似于:
result=$(if $(filter y,${CHECK}),true,false)
(TIMTOWTDI适用)。
shell会获得result=true
或result=false
,具体取决于 make 变量CHECK
的值。
答案 1 :(得分:0)
生成文件
.PHONY: all
all:
@echo "$(filter $(X),$(Y))"
测试
$ make -f make.txt X='xxx yyy' Y='aaa bbb'
$ make -f make.txt X='xxx yyy' Y='aaa xxx'
xxx
$ make -f make.txt X='bbb yyy' Y='aaa bbb'
bbb
GNU Bash在布尔上下文中将非空字符串视为true
。所以具有shell级别条件的配方可能是:
all:
if [[ '$(filter $(X),$(Y))' ]]; then echo "matched!"; else echo "not matched!"; fi