Tan*_*aki 6 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
在任何其他命令执行之前partx错误输出(因此TMPDISK被设置为空)的事实使我认为$(shell)比预期更早地调用.反正有没有将shell调用和赋值延迟TMPDISK到适当的行?
不可能这样拖延扩张。Make 总是先扩展整个配方中的所有变量,然后再将配方的任何部分发送到 shell。没有办法“推迟”到以后。
$(shell ...)一般来说,它并不典型地在配方中使用,因为配方已经在 shell 中运行。在配方 via 中设置 make 变量$(eval ...)也是非常不寻常的。
我建议您重写此配方以使用 shell 变量,而不是 make 变量;这会更容易理解:
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
Run Code Online (Sandbox Code Playgroud)