我对Makefile感到困惑。我试图在Makefile中运行一个简单的命令,但它给我错误“/ bin / bash:line 3 :: =:command not found”。我正在使用shell来运行这个makefile
这是我的Makefile的一部分:
all:
vlog Benchmarks/$(NAME)/Syn/*.v
$(eval tux_number := 1)
$(eval range := 1)
$(eval ssh_log := 255)
echo "Start Range: ${range}"
echo "tux-number: ${tux_number}"
while [[ $$range -le 50 ]] ; do \
ssh -l yazdanbakhsh tux-$(tux_number).cae.wisc.edu exit ; \
echo "range: ${range}" ; \
eval $$range := $$((${range}+1)) ; \
done
由于
答案 0 :(得分:1)
all:
@range=1; \
while [ $$range -le 10 ] ; \
do echo Range: $$range; \
let range=range+1 ; \
done;
请注意@range...
前面的空格是唯一的TAB。
答案 1 :(得分:0)
为了解决您使用Makefile
语法的明显问题,这里尝试将您的尝试重构为有效代码。
tux_number := 1
ssh_log := 255 # not used anywhere
all:
vlog Benchmarks/$(NAME)/Syn/*.v
echo "Start Range: 1" # This is probably no longer very useful output
echo "tux-number: ${tux_number}"
range=1; while [ $$range -le 50 ] ; do \
ssh -l yazdanbakhsh tux-$(tux_number).cae.wisc.edu exit ; \
echo "range: $$range" ; \
range=$$(expr "$$range + 1); \
done
注意tux_number
和ssh_log
是如何构成Makefile变量,而range
仅存在于执行while
循环的shell中。我已经避免使用Bashisms来使这个便携式。 (如果可移植性不重要,您可能希望将其重构为Bash语法并使用for ((range=1; range<=50; range++)); do
...而不是。)
您对eval
的使用是错误的。正如您所看到的,我只是将Makefile变量放在他们不属于的配方之外。你正在做的是(1)让Make评估表达式range := 1
(它评估自己)和(2)将输出用作配方中的shell命令。由于它不是有效的shell命令,因此您从Bash获得了语法错误。不用多说,我会在这里轻松一点,说eval
是一个复杂的主题,直到你获得更多的Make经验,最好忘记它存在。
为了正确使用Make的设施,我会使其可并行化,即将其分成50个单独的目标。这有点笨拙(这里可能有更好的方法来定义range
),但至少它应该说明你的方法有很多不同之处。 (如果你不坚持让range
从1开始计数,那么将它从零开始会使这一点变得不那么笨拙。这会利用空字符串在shell片段中无害的事实,所以我们可以使用它而不是零前缀。再次,如果你不关心范围索引的人类可读性,这可以简化。)
digits := 0 1 2 3 4 5 6 7 8 9
deca := "" 1 2 3 4
range := $(filter-out ""0,$(foreach d,$(deca),$(foreach i,$(digits),$d$i))) 50
# Or, at the expense of an external process,
# range := $(shell perl -le 'print $$_ for 1..50')
.PHONY: all
all: $(patsubst %,ssh-%,$(range))
.PHONY: ssh-%
ssh-%:
ssh -l yazdanbakhsh tux-$(tux_number).cae.wisc.edu exit
echo "range: $*"
例如,可以使用类似make -j 5
的方式运行,以并行批量执行这些操作。
顺便说一句,如果您真正想要做的是使用Make来驱动外部程序为您计算一些内容,那么注释掉的$(shell ...)
调用可能是您问题的实际答案。