makefile中的条件检查

时间:2014-09-10 14:55:50

标签: variables makefile arguments target

考虑以下makefile。我打算把它称为" make var = xxx"正常建筑,"帮助"或"清洁"或者"制作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

它有效,但它有点粗糙......可以简化这一点吗?

3 个答案:

答案 0 :(得分:3)

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

  

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

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

答案 1 :(得分: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
$ 

答案 2 :(得分:0)

我怀疑你也想要以下功能。只有当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