【问题标题】:Conditional checks in makefilemakefile 中的条件检查
【发布时间】:2014-11-04 07:06:08
【问题描述】:

考虑以下生成文件。我打算将其称为“make var=xxx”,用于正常构建,而在其他时候称为“make help”或“make clean”或“make showVars”。当我进行实际构建时,我需要确保在命令行中传递了“var”变量,但我不需要它存在于其他目标,例如 clean。目前,在未指定 var 的任何时候检查都会退出,这很安全,但在清理或乱搞时很烦人且不必要。如何仅对我的构建目标运行检查而不在其他时间运行检查?

var=

$(if $(var),,$(error var was not specified at commandline!))

var_RELEASE=`echo $(var) | sed -e 's/-/_/g'`

.PHONY all showVars clean prep rpm

all: prep rpm

prep:
# Do prep work. Requires valid var and var_RELEASE

rpm:
# Build rpm. Requires valid var_RELEASE

help:
# Does not require var and var_RELEASE

showVars:
# Display all vars. Requires valid var and var_RELEASE

clean:
# Does not require var and var_RELEASE

更新:

根据以下 Maxim 的建议,使用 $(MAKECMDGOALS) 检查指定了哪个目标并忽略任何不需要设置 var 的目标:

# Check if var is empty for prep and rpm targets, bail out if so.
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),help)
ifneq ($(MAKECMDGOALS),showvars)
$(if $(var),,$(error var was not specified at commandline! See 'make help'))
endif
endif
endif

它可以工作,但它有点粗糙......可以简化这个吗?

【问题讨论】:

  • 您可以使用filter:ifeq (,$(filter clean help showvars,$(MAKECMDGOALS))),然后检查var,如果没有设置则失败。

标签: variables makefile arguments target


【解决方案1】:

我怀疑您还需要以下功能。仅当 VAR 的值(允许我更改为大写,我喜欢这样的变量)发生更改时,您才会想要重建需要它的目标。就像VAR 是一个文件,但它不是,它是一个变量。

我将使用此附加功能解决您的问题。

在这种情况下,我使用我所谓的“可靠变量”。通常,Make 使用文件作为先决条件。我们可以修改一个变量以使其表现得像这样。

此外,当变量未指定或指定但为空时,您将获得所需的诊断投诉类型。

之所以加倍功能,是因为这样更方便我的用户,调用DEPENDABLE_VAR函数,他们不必知道eval的任何事情。

你在这里:

define DEPENDABLE_VAR_FUNCTION

$(shell \
if [[ `cat $1 2>/dev/null` != '$($1)' ]]; then \
    echo -n $($1) > $1 ; \
    if [ ! -s $1 ]; then \
        rm $1 ; \
    fi; \
fi)

endef

define DEPENDABLE_VAR
$(eval $(call DEPENDABLE_VAR_FUNCTION,$1))
endef


# declare VAR to be dependable
$(call DEPENDABLE_VAR,VAR)

.PHONY: all clean
all: rpm

rpm: VAR
    touch $@

clean:
    rm -rf VAR rpm

【讨论】:

    【解决方案2】:

    另一种可能的解决方案是添加一个虚假目标来检查配方中的变量:

    var=
    
    var_RELEASE=`echo $(var) | sed -e 's/-/_/g'`
    
    .PHONY: all showVars clean prep rpm checkVar
    
    all: prep rpm checkVar
    
    prep:
    # Do prep work. Requires valid var and var_RELEASE
    
    rpm:
    # Build rpm. Requires valid var_RELEASE
    
    help:
    # Does not require var and var_RELEASE
    
    showVars:
    # Display all vars. Requires valid var and var_RELEASE
    
    clean:
    # Does not require var and var_RELEASE
    
    checkVar:
        @if [ ! "$(var)" ]; then \
            echo "var was not specified"; \
            return 1; \
        fi
    

    all 现在依赖于checkVar 目标,如果$(var) 扩展为非空字符串,则其配方是一个简单的shell 测试。如果$(var) 为空,则配方将返回一个非零返回码,并且 make 将出错,并显示有用的消息:

    $ make
    var was not specified
    make: *** [checkVar] Error 1
    $ make var=hello
    $ 
    

    【讨论】:

      【解决方案3】:

      您可以使用MAKECMDGOALS 找出在命令行中指定了哪些目标:

      Make 会将特殊变量 MAKECMDGOALS 设置为您在命令行中指定的目标列表。如果命令行上没有给出目标,则此变量为空。请注意,此变量应仅在特殊情况下使用。

      或者,您可以在 makefile 中将所有这些变量设置为其默认值。在命令行上对变量的赋值会覆盖 makefile 中的值。这样,只有在默认值不合适时,用户才必须指定这些变量的值。

      【讨论】:

      • 问题在于,我不希望在 makefile 中设置值(作为“默认值”)。对于某些目标,用户必须指定一个值,否则进程必须停止(如果在这种情况下我可以打印出我的“make help”目标的结果,那就太好了——加分)。但是,其他目标不需要值。
      • 嗯,但该变量确实提供了一些帮助......请参阅我修改后的帖子以及我当前的实现。不漂亮,但它有效。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-26
      • 2011-07-08
      • 2017-07-28
      • 2012-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多