Makefile变量赋值尽早执行

时间:2014-04-10 21:24:42

标签: makefile eval variable-assignment

我有一个Makefile规则,需要将shell命令的结果存储到变量中供以后使用。出于某种原因,似乎$(shell)调用在我的规则匹配时执行,而不是在执行期间遇到它。

该文件如下:

TMPDEV=/tmp/disk.img

$(TMPDEV):
        fallocate -l 806354944 $(TMPDEV)
        sudo parted --script $(TMPDEV) unit s mklabel msdos \
          mkpart primary fat16 2048 526335 \
          mkpart primary fat32 526336 1050623 \
          mkpart primary NTFS 1050624 1574911 \
          quit
        $(eval TMPDISK := $(shell sudo partx --verbose -a $(TMPDEV) | tail -1 | cut -d':' -f1))
        echo $(TMPDISK)
        sudo mkfs.fat -F 16 -n FAT16 $(TMPDISK)p1

至少在TMPDISK电话之后,才能知道fallocate的价值是什么;这就是$(eval)语句延迟到磁盘映像分区之后的原因。

我收到的输出是:

$ make
partx: stat failed /tmp/disk.img: No such file or directory
fallocate -l 806354944 /tmp/disk.img || dd if=/dev/zero of=/tmp/disk.img bs=1b count=1574912
sudo parted --script /tmp/disk.img unit s mklabel msdos \
  mkpart primary fat16 2048 526335 \
  mkpart primary fat32 526336 1050623 \
  mkpart primary NTFS 1050624 1574911 \
  quit
echo

在执行任何其他命令之前partx错误(因此TMPDISK设置为空)的事实让我认为$(shell)的调用早于预期。无论如何将shell调用和赋值延迟到TMPDISK直到相应的行?

2 个答案:

答案 0 :(得分:4)

不可能像这样延迟扩展。在将配方的任何部分发送到shell之前,Make始终首先展开整个配方中的所有变量。没有办法推迟"直到以后。

通常,在配方中使用$(shell ...)并不常见,因为配方已经在shell中运行。通过$(eval ...)在食谱中设置变量也非常不寻常。

我建议您重写此配方以使用shell变量,而不是变量;这将更容易理解:

TMPDEV=/tmp/disk.img

$(TMPDEV):
        fallocate -l 806354944 $(TMPDEV)
        sudo parted --script $(TMPDEV) unit s mklabel msdos \
          mkpart primary fat16 2048 526335 \
          mkpart primary fat32 526336 1050623 \
          mkpart primary NTFS 1050624 1574911 \
          quit
        TMPDISK=$$(sudo partx --verbose -a $(TMPDEV) | tail -1 | cut -d':' -f1); \
          echo $$TMPDISK; \
          sudo mkfs.fat -F 16 -n FAT16 $${TMPDISK}p1

答案 1 :(得分:2)

我遇到了同样的问题。即使在目标命令运行之前,eval命令也会扩展。以下是Simon Gibbons的回答。

makefile variable assignment under a target

解决方案是为" fallocate"添加另一个目标。命令并将其作为依赖项添加到$(TMPDEV)目标。