foreach中的条件变量(ifeq)用于显式make规则

时间:2015-07-25 03:04:33

标签: gnu-make

我无法弄清楚在GNU Make 3.81中使用带有foreach循环的条件定义变量的正确语法。

一个简单的makefile

SET := A B C

define da_loop

ifeq ($(S), A)
    T := equals_A
else
    T := not_equals_A
endif

out_$(S):
    echo "$(S) $$(T)"

endef

$(foreach S, $(SET), $(eval $(call da_loop, $S)))

预期产出:

$ make out_A out_B out_C
echo "A equals_A"
A equals_A
echo "B not_equals_A"
B not_equals_A
echo "C not_equals_A"
C not_equals_A

实际输出:

$ make out_A out_B out_C
echo "A not_equals_A"
A not_equals_A
echo "B not_equals_A"
B not_equals_A
echo "C not_equals_A"
C not_equals_A

将“eval”更改为“info”在我看来应该这样:

ifeq (A, A)
        T := equals_A
else
        T := not_equals_A
endif

out_A:
        echo "A $(T)"


ifeq (B, A)
        T := equals_A
else
        T := not_equals_A
endif

out_B:
        echo "B $(T)"


ifeq (C, A)
        T := equals_A
else
        T := not_equals_A
endif

out_C:
        echo "C $(T)"

我已经尝试了额外的“$”,引号,= vs:=的每一个组合,我能想到,但还没有一个工作。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

问题与循环,Map("aba" -> 0.2, "abb" -> 0.8)等无关。问题比这更简单,更基础:在make中,变量全局定义,所有规则都只是在解析整个makefile之后调用。 eval技巧实际上是DID向您展示问题。让我们简化一下:

info

问题是所有变量赋值都是在读入makefile时发生的,但是配方的扩展直到很久以后才会发生,当make构建目标并决定运行配方时。因此,您的makefile可以等效地编写为:

T := equals_A
out_A:
        echo "A $(T)"

T := not_equals_A
out_B:
        echo "B $(T)"

T := not_equals_A
out_C:
        echo "C $(T)"

现在你可以看到为什么你会得到你的行为。

有很多方法可以“修复”这个,其中哪些最合适取决于你真正想要在真正的makefile中做什么。一个非常简单的选择是使用target-specific variables,如下所示:

T := equals_A
T := not_equals_A
T := not_equals_A

out_A:
        echo "A $(T)"
out_B:
        echo "B $(T)"
out_C:
        echo "C $(T)"

通过使用它,您已指定每个SET := A B C define da_loop ifeq ($(S), A) out_$(S): T := equals_A else out_$(S): T := not_equals_A endif out_$(S): echo "$(S) $$(T)" endef $(foreach S, $(SET), $(eval $(call da_loop, $S))) 变量绑定到该特定目标的范围,并且每个目标可以具有不同的值。其他选项可以是构造变量名,或者只是使用T函数将值直接扩展到配方中,而不是将其设置为单独的变量。

答案 1 :(得分:-1)

image
ifeq当然有另一种语法(带引号),
在引用的文本中没有完成白色空间的剥离!