在Makefile中进行计算

时间:2013-08-18 17:37:19

标签: shell makefile

我对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

由于

2 个答案:

答案 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_numberssh_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 ...)调用可能是您问题的实际答案。