生成文件
abc:
TEST=$@ /* TEST=abc */
def:
TEST=$@ /* TEST=def */
xxx:
@echo $(TEST)
如果我运行make abc xxx
,我
期望输出abc
。
如果我运行make def xxx
,我
期望输出def
。
但它没有那样的工作。好像make
似乎不允许我在目标中定义一个变量。我的问题是如何定义一个变量及其值取决于构建哪个目标?
答案 0 :(得分:3)
使用GNU Make,您可以按如下方式复制Makefile的预期结果:
echo.%:
@echo $*
或简单地说:
%:
@echo $*
这些允许您分别指定make echo.abc
或make 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。