假设以下Makefile
(请参见此处):
target-1-raw:
target-1-body
target-2-raw:
target-2-body
target-3-raw:
target-3-body
%-raw:
echo "Error: Target $@ does not exist!"
%:
@$(MAKE) $@-raw 3>&2 2>&1 1>&3
我正在努力确保用户调用它时没有后缀-raw
,例如:
make target-1
而不是像这样:
make target-1-raw
因此,我想在目标%
的规则中设置一个变量,并从所有其他目标中检查是否设置了这个变量:
check:
#??? If FLAG is not set, then abort with an error message.
target-1-raw: check
target-1-body
target-2-raw: check
target-2-body
target-3-raw: check
target-3-body
%-raw:
echo "Error: Target $@ does not exist!"
%:
#??? set FLAG
@$(MAKE) $@-raw 3>&2 2>&1 1>&3
我尝试了各种方法来实现从#???
开始的行,但都没有成功。如果我使用make
的设施(例如ifndef
和ifeq
,那么事情似乎不会在我希望的时候得到评估)。我也尝试使用shell的if []
,但没有成功。那么,如果这是可能实现的,那么我的朋友在这里是什么工具?
我正在努力确保用户在没有后缀
-raw
的情况下调用它
我不明白这有什么用。make
和Makefiles是针对那些通常需要了解自己在做什么的人的工具。没有什么特别的理由可以积极阻止Makefile的用户在没有流交换的情况下执行构建,如果这是他们真正想要的话。
因此,我想在目标%的规则中设置一个变量,并从所有其他目标中检查是否设置了该变量。
不可能。make
配方中的每个逻辑行都由一个单独的shell执行。这些命令是shell命令,而不是make
命令,通过这些命令设置的任何变量都不会在命令完成时退出shell。
那么,如果这是可能实现的,那么我的朋友在这里是什么工具?
make
配方记录后续命令或规则的持久信息的主要机制是写入文件。这些文件的内容,甚至它们的存在,都可以用来影响后续的命令。然而,对于像你这样的工作来说,这似乎是极其脆弱的。尽管如此,它可能看起来是这样的:
target-1-raw:
temp='$@'; test -e $${temp%-raw}-check
|| echo warning: target '$@' made directly
target-1-body
%-raw:
echo "Error: Target $@ does not exist!"
%:
touch $@-check
@$(MAKE) $@-raw 3>&2 2>&1 1>&3
rm $@-check
然而,我向你保证,如果我收到一个包含这样一个结构的Makefile
,我不会留下深刻印象,我的第一个冲动就是把它撕下来。我建议你不要再把用户的自由看作是一个需要解决的问题。