Makefile变量分配尽早执行 [英] Makefile Variable Assignment Executes Early

查看:76
本文介绍了Makefile变量分配尽早执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Makefile规则,该规则要求将Shell命令的结果存储到变量中以备后用.由于某些原因,$(shell)调用似乎在我的规则匹配后立即执行,而不是在执行过程中遇到时.

I have a Makefile rule that requires storing the results from shell commands into variables for later use. For some reason, it seems that the $(shell) call executes as soon as my rule is match, as opposed to when it is encountered during execution.

文件如下:

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

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

It is impossible to know what the value of TMPDISK will be until at least after the fallocate call; that is why the $(eval) statement is delayed until after the disk image is partitioned.

我收到的输出是:

$ 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的分配延迟到适当的行?

The fact that partx errors out (and thus TMPDISK is set to empty) before any of the other commands execute makes me think that $(shell) is called earlier than intended. Is there anyway to delay the shell call and the assignment to TMPDISK until the appropriate line?

推荐答案

无法像这样延迟扩展.在将配方的任何部分发送到外壳之前,Make始终先扩展整个配方中的所有变量.直到以后,才有办法推迟".

It is not possible to delay expansion like this. Make always expands all the variables in the entire recipe first, before it sends any part of the recipe to the shell. There is no way to "defer" that until later.

通常,在配方中使用$(shell ...)并不常见,因为该配方已在外壳中运行.通过$(eval ...)在配方中设置make变量也非常不常见.

Generally, it's not typical to use $(shell ...) in a recipe, since the recipe is already running in a shell. And setting make variables inside a recipe via $(eval ...) is also highly unusual.

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

I would recommend that you rewrite this recipe to use shell variables, not make variables; it will be much more understandable:

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

这篇关于Makefile变量分配尽早执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆