从 makefile 中的 bash 命令输出创建变量

Creating variable from bash command output in makefile

你好我想问一下如何在makefile中创建bash变量。 下面的代码确实有效,但变量“目标”一直为空。我如何在 makefile 中实际创建“目标”和“current_target”变量?问题是我必须从实际的 bash 命令创建这个变量。

SHELL=/bin/bash
...
MAIN_APPS = 01_prep 02_prep 03_prep 04_prep 05_prep
foo : .check_targets .check_segment 
    @for f in $(MAIN_APPS) ; do \
        targets=$(expr $(last_target) + 1); \
        echo $(targets) + 1; \
        curent_target=$(expr "$(echo $(f) | head -c 2) + 0"); \
        if [ $(targets) = $(current_target)]; then \
            break; \
        else \
            make $(f); \
        fi \
    done

输出:

make foo last_target="02" segm=KI
+ 1

我想做的是从我的 makefile 创建目标,如果我传递一个参数 last_target="05"

,它实际上从 01 到 05 开始

您混淆了 make 变量和 shell 变量。而且您没有考虑到 make 在将食谱传递给 shell 之前扩展了食谱,这是您经常需要使用 $$ 而不是 $ 的原因。或者,对于命令扩展,`...` 而不是 $(...)。您还在不应该使用的地方使用双引号 (expr "...")。最后,您在食谱中使用 make,这不是一个好主意。您应该使用 $(MAKE)(有关详细信息,请参阅 How the MAKE Variable Works section of the GNU make manual)。

也许可以尝试以下(未测试):

SHELL=/bin/bash
...
MAIN_APPS = 01_prep 02_prep 03_prep 04_prep 05_prep
foo : .check_targets .check_segment 
    @for f in $(MAIN_APPS) ; do \
        targets=`expr "$(last_target)" + 1`; \
        echo "$$targets + 1"; \
        tmp=`echo "$$f" | head -c 2`; \
        curent_target=`expr "$$tmp" + 0`; \
        if [ "$$targets" = "$$current_target" ]; then \
            break; \
        else \
            $(MAKE) "$$f"; \
        fi \
    done

但我几乎 100% 相信您正在尝试将 make 用作一种脚本语言,而不是用作复杂的构建系统。如果我理解得很好,您正试图通过指定最后一个目标编号来仅重建 MAIN_APPS 的一个子集。您可能可以使用更加虚构的风格来实现相同的效果:

TARGETS := $(shell printf '%02d_prep\n' $$(seq $(last_target)))

.PHONY: foo
foo: $(TARGETS) .check_targets .check_segment

仅此而已,foo 没有复杂的配方。什么都没有(当然,除了构建 .check_targets.check_segment 和所有 xx_prep 目标的规则,您没有显示)。

说明:我使用 $(shell ...) make 函数和一个小的 shell 脚本将 make 变量 TARGETS 初始化为 01_prep 02_prep ... 直到 $(last_target)_prep。如评论中所述,此 shell 脚本甚至不需要 bash 并且可以使用默认 make shell (sh)。因此,如果您没有其他充分理由使用 bash,请删除 SHELL=/bin/bash 行,您的 Makefile 将更加便携。

然后,我将 foo 声明为假文件,因为您可能没有名为 foo 的文件,如果您有一个文件,您可能需要 make 来构建 foo无论如何。

最后,我宣布$(TARGETS).check_targets.check_segmentfoo的先决条件。如果您要求 make 构建 foo 而这些先决条件中的任何一个都已过时,make 将使用您为它声明的规则来构建它。

这更像是制作,因为它清楚地告诉制作取决于什么,而不是将其隐藏在食谱中。 make 需要这个来正确地完成它的工作,这包括比较文件的最后修改日期来决定是否必须重建某些东西。它还具有额外的好处,例如,如果可能的话,利用计算机的并行性来并行构建多个 xx_prep