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