2014-09-10 151 views
0

请考虑以下makefile。我打算在正常建筑中称其为“make var = xxx”,并在其他时间称其为“make help”或“make clean”或“make showVars”。当我进行实际构建时,我需要确保'var'变量在命令行中传递,但我不要求它为其他目标(如clean)提供它。目前,检查任何时候都没有指定var,这是安全的,但是在清理或者扒手时很麻烦并且不必要。我怎样才能运行检查我的生成目标而不是在其他时间?makefile中的条件检查

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 

UPDATE:

每低于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 

它的工作原理,但它有点粗糙...可以简化这一切?

+1

你可以用'filter':'IFEQ($(过滤器的清洁帮助showvars,$(MAKECMDGOALS)))'然后检查'var',如果没有设置失败。 – MadScientist 2014-09-10 23:29:38

回答

3

你可以使用MAKECMDGOALS找出哪些目标已在命令行上指定:

制作将设置特殊变量MAKECMDGOALS到你的命令行上指定目标的清单。如果在命令行上未给出目标,则此变量为空。请注意,此变量只能在特殊情况下使用。

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

+0

问题在于,我不想在makefile中设置值(如“默认值”)。对于某些目标,用户必须指定一个值,或者该过程必须停止(并且这将非常好 - 奖励点 - 如果我可以在此情况下打印出“帮助”目标的结果)。但是,其他目标不需要价值。 – Jon 2014-09-10 17:48:50

+0

嗯,但该变量确实提供了一些帮助...看我修改后的文章与我目前的实施。不漂亮,但它的作品。谢谢! – Jon 2014-09-10 17:55:46

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)膨胀到非空字符串。如果$(var)是空的,那么配方将返回一个非零返回代码,并会报错了,有一个有用的信息:

$ make 
var was not specified 
make: *** [checkVar] Error 1 
$ make var=hello 
$ 
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 [email protected] 

clean: 
    rm -rf VAR rpm