首页 > 解决方案 > 在 Makefile 中多次评估动态宏

问题描述

我有一个用例,我需要在规则中多次运行相同的命令。但是,命令参数需要根据另一个命令的返回值进行更改。我发现可以$(call foo_exec)从规则中调用宏,这很棒。但是,请考虑以下简化代码:

define foo_exec
        @echo $(if $(filter sylvester,$(shell cat cats.txt)),Found Sylvester!,No Sylvester found!)
endef

build:
        $(call foo_exec)
        @echo sylvester > cats.txt
        $(call foo_exec)

如果我运行make build,我会得到以下输出:

cat: cats.txt: No such file or directory
cat: cats.txt: No such file or directory
No Sylvester found!
No Sylvester found!

它肯定会写cats.txt,但是,在创建该文件之前,宏似乎只被评估一次。

此外,在我的真实代码中,在该宏中创建变量是有益的,但我似乎也无法完成这项工作。以下代码:

define foo_exec
        MESSAGE := $(if $(filter sylvester,$(shell cat cats.txt)),Found Sylvester!,No Sylvester found!)
        @echo $(MESSAGE)
endef

build:
        $(call foo_exec)
        @echo sylvester > cats.txt
        $(call foo_exec)

产生这个输出:

cat: cats.txt: No such file or directory
cat: cats.txt: No such file or directory
MESSAGE := No Sylvester found!
/bin/sh: MESSAGE: command not found
make: *** [build] Error 127

在这一点上,我开始觉得宏可能不是实现所需功能的正确方法,但我不确定如何去做并避免重复大量代码。欢迎任何建议!

标签: shellmakefile

解决方案


以下作品

define foo_exec
        @if egrep -s -q sylvester cats.txt; then echo "Found Sylvester"; else echo "No Sylvester found!"; fi
endef

build:
        $(call foo_exec)
        @echo sylvester > cats.txt
        $(call foo_exec)

有了这个输出:

$ make build
No Sylvester found!
Found Sylvester

问题是宏在build配方开始时被扩展。因此,我们不希望宏扩展检查cats.txt文件是否存在。相反,我们希望宏生成将执行检查的 bash 代码

我可能解释得不是很好!


推荐阅读