显然 GNU Make 条件中没有布尔类型,所以这似乎是最好的解决方案:
$(DEF_TARGET):
if [ "$(CHECK)" != "y" ]; then \
var=foo; \
$(if $(filter foo,$(var)),result=true,result=false); \
fi
Run Code Online (Sandbox Code Playgroud)
问题是,无论是var=foo还是var=bar,result永远都是false。替换$(var)为foo或bar将产生正确的结果。
为什么这不起作用?有没有更好的解决问题的方法?
使用命令运行以下 makefile make -f make.txt
.PHONY: all
all:
X=aaa; \
Y=aaa; \
if [[ '$(filter $(X),$(Y))' ]]; then echo "matched!"; else echo "not matched!"; fi
Run Code Online (Sandbox Code Playgroud)
输出:
X=aaa; \
Y=aaa; \
if [[ '' ]]; then echo "matched!"; else echo "not matched!"; fi
not matched!
Run Code Online (Sandbox Code Playgroud)
为什么当它失败X,并Y在目标配方被赋值?
显然 GNU Make 条件中没有布尔类型
显然有,否则$(if ...)宏的存在是没有意义的!
读取配方(即构建目标的shell 命令块)的方法是理解make将配方存储为单个递归扩展变量。只有当make需要将一些命令传递给 shell时才会扩展配方。
配方整体扩展一次。然后逐行执行结果扩展的每一行。每次执行都在shell 的一个新实例中运行。
因此,以您的原始 makefile 为例,假设您已要求make构建${DEF_TARGET}.
Make扩展配方:
Run Code Online (Sandbox Code Playgroud)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 expands $(if ,result=true,result=false),result=false当然会产生。
if [ "" != "y" ]; then \
var=foo; \
result=false; \
fi
Run Code Online (Sandbox Code Playgroud)
由于反斜杠,Make将其视为一行。
所以,不要混淆shell变量和make变量。当 shell 拿到配方时,所有的make变量都消失了。 Make对 shell 变量一无所知。
您的原始 shell 代码段可能类似于:
result=$(if $(filter y,${CHECK}),true,false)
Run Code Online (Sandbox Code Playgroud)
(TIMTOWTDI 适用)。外壳获取result=true或result=false取决于make变量的值CHECK。
| 归档时间: |
|
| 查看次数: |
7185 次 |
| 最近记录: |