gnu makefile:shell函数在配方中的执行顺序

问题描述 投票:1回答:1

我在Makefile配方中使用$(shell ...)gnu make函数,它首先在前面的行之前运行。为什么?

一个非常简单的示例:

.PHONY: all
all:
    @echo 1
    @echo $(eval a=$(shell echo 2a 1>&2))2b
    @echo 3 $(a)

输出为:

2a
1
2b
3

首先运行$(shell ...)行(2a),然后运行其他行。当行在配方中按此顺序运行时,如何管理$(shell ...)函数?

1
2a
2b
3

编辑:

没有$(shell ...),它可以正常工作,我期望:

.PHONY: all
all:
    @echo 1
    $(eval a=a)
    @echo 2 $(a)
    $(eval a=b)
    @echo 3 $(a)

输出:

1
2 a
3 b

编辑2:这是原始Makefile的一部分。粗体显示了我的问题的本质:我想将udisksctl的输出放入一个make变量中,而不是文件$ @。loop中(并使用$ @。mount进行同样的操作)。

$(HDIMG): $(BOOTBLOCK_MBR_BIN) $(BOOTBLOCK_EXT2_BIN) $(LOADER_BIN) | $(DESTDIR)
        dd if=/dev/zero [email protected] bs=1 seek=$(PSIZEB) count=0 2>/dev/null
        $(MKFSEXT2) -F [email protected] >/dev/null
        dd if=$(word 2,$^) [email protected] conv=notrunc 2>/dev/null
        cp $< $@
        dd if=/dev/zero of=$@ bs=1 seek=$(HDSIZEB) count=0 2>/dev/null
        echo $(PFDISK) | $(TR) | $(FDISK) $@ >/dev/null
        dd [email protected] of=$@ bs=512 seek=$(PSTART) conv=sparse,notrunc iflag=fullblock 2>/dev/null
        **udisksctl loop-setup --file $@ --offset $(PSTARTB) --size $(PSIZEB) >[email protected]**
        sed -i -e 's/.* //;s/\.//' [email protected]
        cat [email protected]
        udisksctl mount --block-device **$$(cat [email protected])** >[email protected]
        sed -i -e 's/.* //;s/\.//' [email protected]
        cat [email protected]
        #
        mkdir -p $$(cat [email protected])/boot/
        cp $(word 2,$^) $$(cat [email protected])/boot/
        #/sbin/filefrag -b512 -e /
        #
        udisksctl unmount --block-device $$(cat [email protected])
        udisksctl loop-delete --block-device $$(cat [email protected])
        rm [email protected]
makefile gnu-make
1个回答
0
投票

make运行配方时,它first展开其中的所有变量/功能,而then逐行运行shell命令。

您可以通过使用$(shell ...)执行every shell命令来解决此问题,或者在您的情况下,使用$(info ...)而不是echo

.PHONY: all
all:
    $(info 1)
    $(info $(eval a=$(shell echo 2a 1>&2))2b)
    $(info 3 $(a))

输出:

1
2a
2b
3
make: Nothing to be done for 'all'.

Nothing to be done for 'all'.部分是由于以下事实引起的:展开功能后,配方实际上为空(具有0个Shell命令)。向其添加无操作命令(例如@true)会删除该消息。

© www.soinside.com 2019 - 2024. All rights reserved.