Makefile ifeq:何时评估它们?
下面是一个似乎无法正常工作的非常简单的makefileMakefile 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
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