Makefile ifeq:何时评估它们?

Makefile ifeq:何时评估它们?,makefile,gnu-make,Makefile,Gnu Make,下面是一个似乎无法正常工作的非常简单的makefile TEST=ON buildbegin: ifeq ($(TEST),ON) @echo TEST PASSED else @echo TEST FAILED endif 无论我将测试变量设置为什么,我的ifeq语句都会通过。我总是看到考试通过。有人知道我做错了什么吗 编辑: 嗯。我的例子并不完全准确。我实际拥有的是: SHELL = /bin/sh DEFAULT_TARGS:= all all_de

下面是一个似乎无法正常工作的非常简单的makefile

TEST=ON

buildbegin:
ifeq ($(TEST),ON)        
    @echo TEST PASSED
else
    @echo TEST FAILED
endif
无论我将测试变量设置为什么,我的ifeq语句都会通过。我总是看到考试通过。有人知道我做错了什么吗

编辑:

嗯。我的例子并不完全准确。我实际拥有的是:

SHELL = /bin/sh

DEFAULT_TARGS:= all  all_debug  
DEBUG_TARGS:= all_debug
ALL_TARGS:= $(DEFAULT_TARGS) $(DEBUG_TARGS)

.PHONY: $(ALL_TARGS)
.PHONY: buildbegin

$(ALL_TARGS): buildbegin

TEST=ON

$(DEBUG_TARGS): TEST=OFF

buildbegin:
    @echo $(TEST)
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif

运行makeall或makeall_调试将导致打印“PASSED”。如果我在条件之前回显$(TEST),看起来好像我的规则正在更改变量,但ifeq只会看到默认值。

make在读取makefile时对条件进行求值(如您所知,它使用了两次传递),请参阅:。您只需使用warning(这是调试makefiles的一件好事)来检查这一点:

您应该改用shell命令,并将其包含在规则中:

buildbegin:
      @if [ "$(TEST)" = "ON" ]; then echo "PASSED"; else echo "FAILED"; fi
以下是一种清洁剂(无论如何,我认为)可以满足您的需求:

all:
    $(MAKE) TEST=ON buildbegin

all_debug:
    $(MAKE) TEST=OFF buildbegin

buildbegin:
    @echo $(TEST)
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif

使用make变量参数化shell命令。这避免了递归make甚至shell(如果命令不包含shell元字符(&;等等),make将直接派生命令,而不是通过shell)

比如:

result<ON> := PASSED
result<OFF> := FAILED

buildbegin:
    @echo ${result-<${TEST}>}
result:=已通过
结果:=失败
构建开始:
@echo${result-}

只是一种表示某种间接方式的约定。

尽管这个问题很老,但我想分享一种更简单的方式

这是为了使用表示目标列表的变量

在您的情况下,解决方案可能是:

buildbegin:
    @echo $(MAKECMDGOALS)
ifeq ($(MAKECMDGOALS),all)
    @echo PASSED
else ifeq ($(MAKECMDGOALS),debug_all)
    @echo FAILED
endif


debug_all: buildbegin

all: buildbegin

用法:
make debug\u all
make all

对我有效-
GNU make 3.82
在这里也有效-GNU 3.81抱歉。我的示例有缺陷。我发布了一个带有真实example@user1604180欢迎来到SO!如果这个答案是正确的(当然是正确的),您应该这样做。@kralyk感谢您指出这一点,在本例中,它实际上应该是$(TEST),因为我们希望它由make进行计算。但是如果您需要在shell中进行计算(不是在本例中),那么是的-您应该使用$$TEST。但是请注意,每一行都是在自己的shell进程中执行的,因此在本例中,您需要计算“在测试前的一个生成行中,“@pmod Sub make继承父生成的环境,因此不需要显式复制变量。
buildbegin:
    @echo $(MAKECMDGOALS)
ifeq ($(MAKECMDGOALS),all)
    @echo PASSED
else ifeq ($(MAKECMDGOALS),debug_all)
    @echo FAILED
endif


debug_all: buildbegin

all: buildbegin