生成文件
abc:
TEST=$@ /* TEST=abc */
def:
TEST=$@ /* TEST=def */
xxx:
@echo $(TEST)
如果我运行make abc xxx
,我期望输出abc
。
如果我运行make def xxx
,我期望输出def
。
但它不是那样工作的。似乎make
不允许我在目标中定义变量。我的问题是如何定义取决于构建的目标的变量及其值?
使用 GNU Make,您可以复制 Makefile 的预期结果,如下所示:
echo.%:
@echo $*
或者简单地说:
%:
@echo $*
这些将允许您分别指定make echo.abc
ormake abc
并将abc
其视为输出。
这一切都很好,但听起来你会对特定于目标的变量更感兴趣。如果变量值依赖于目标名称,但不是目标名称的子字符串,则可以执行以下操作:
%:
@echo $(TEST)
abc: TEST=xyzzy
def: TEST=plugh
这允许您指定make abc
并查看xyzzy
为输出。
如果您想超越这一点,以便目标的行为根据命令行上指定的其他目标而改变,我们有两个选择:要么让.PHONY
目标更新主要目标使用的文件,要么进行一些处理MAKECMDGOALS
变量:
选项1:
xxx: xxx.temp
@cat xxx.temp
@rm xxx.temp
abc def:
@echo $@ > xxx.temp
.PHONY: xxx abc def
这依赖于命令行目标按顺序处理的事实(如果您指定多个目标,请按照您命名它们的顺序依次处理每个目标。 -GNU Make Manual,第 9.2 节),因此您必须指定make abc xxx
和不是make xxx abc
。
选项 2:
ifneq (,$(findstring abc,$(MAKECMDGOALS)))
VAR=abc
else ifneq (,$(findstring def,$(MAKECMDGOALS)))
VAR=def
endif
xxx:
@echo $(VAR)
abc def:
@echo -n > /dev/null
.PHONY: xxx abc def
@echo -n > /dev/null
抑制make: Nothing to be done for 'abc'.
消息。这对我来说似乎更笨拙,如果您可以容忍临时文件,我会推荐选项 1。