假设以下Makefile
(请参阅here它的优点):
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 []
,但没有成功。那么,如果这完全可以实现,那么我的朋友在这里使用什么工具?
答案 0 :(得分:1)
我正在尝试确保用户在没有后缀
的情况下调用它-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
,那么我就不会留下深刻的印象,而我的第一个冲动就是把它撕掉。我建议您不要将用户的自由视为需要解决的问题。