我正在编写一个名为 run.mk 的简单makefile,如下面的代码所示。
a = 0
b := $(shell echo `expr $(a) + 1`)
app: main.o
gcc -o app main.o
main.o: main.c
gcc -c main.c
test:
while [ $(a) -lt 10 ];\
do\
echo $(a);\
a:= $(shell echo `expr $(a) + 1`);\
echo $(a);\
done
当我使用命令 make -f run.mk test 运行此makefile时,出现错误: a not found 并且循环无限运行,即变量a的值未更新在while循环中的 a:= $(shell echo expr $(a) + 1
)。但是在开始时,变量b的值通过相同的代码行 $(shell echo expr $(a) + 1
)设置为1。有人请告诉我如何在循环中更新变量a的值。
谢谢。
答案 0 :(得分:4)
你混淆了make
语法和shell语法。配方中的命令由shell运行(在make扩展它们一次之后)。 shell是一个单独的进程,shell中发生的任何事情都是完全不可见的。所有make看到的是退出代码(知道是否有错误)。 shell无法以任何方式修改make的行为(更改变量值等)
因此,使用您的规则make make会首先扩展test
的配方(顺便说一句,这对于目标来说是一个非常糟糕的名称,因为test
实际上是您系统上已有的真实程序),得到这个结果:
while [ 0 -lt 10 ]; \
do \
echo 0; \
a:= 1; \
echo 0;\
done
在扩展完成之后,它将该文本发送到shell执行,显然这将永远运行(同样,请注意a:= 1
不是有效的shell命令。)
既然你只是告诉了我们你尝试了什么但是没有告诉我们你最初想做什么,我们无法帮助你做你想做的事。
如果您要做的是编写一个将循环10次打印值的配方,您必须完全使用shell语法,而不是make语法。像这样:
test:
a=$(a); \
while [ $$a -lt 10 ];\
do\
echo $$a;\
a=`expr $$a + 1`;\
echo $$a;\
done
$$
转义变量不被make扩展,导致shell运行这个shell脚本:
a=0; \
while [ $a -lt 10 ];\
do\
echo $a;\
a=`expr $a + 1`;\
echo $a;\
done
答案 1 :(得分:1)
您正在混合shell脚本变量并生成变量。
test
的食谱是一个shell脚本(从while
到done
)。使变量(例如$(a)
)在开始执行之前展开,因此while
行while [ 0 -lt 10 ]
始终为真。
赋值a:=...
不起作用,因为它是makefile语法,而不是shell语法。即使它确实有效,也不会影响while
行。