检查父项设置的变量是否存在

时间:2016-05-19 13:34:31

标签: bash makefile sh

假设以下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的设施(例如ifndefifeq,那么事情似乎不会在我希望的情况下进行评估)。我也尝试使用shell if [],但没有成功。那么,如果这完全可以实现,那么我的朋友在这里使用什么工具?

1 个答案:

答案 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,那么我就不会留下深刻的印象,而我的第一个冲动就是把它撕掉。我建议您不要将用户的自由视为需要解决的问题。