我正在编写一个需要定义一些环境变量的makefile。我试图用这样的东西来实现这个目标:
define check-var-defined
ifndef $(1)
$(error $(1) is not defined)
endif
endef
$(call check-var-defined,VAR1)
$(call check-var-defined,VAR2)
$(call check-var-defined,VAR3)
rule1:
#stuff
当我在没有args的情况下运行make时,我得到了这个:
$ make
Makefile:7: *** VAR1 is not defined. Stop.
但是当我用VAR1指定运行它时,我得到了同样的错误。
$ make VAR1=hello
Makefile:7: *** VAR1 is not defined. Stop.
为什么这不起作用的任何想法?我能做些什么来完成这项工作?提前谢谢。
(注意,我需要检查变量是否在运行makefile时实际定义,因为我需要进一步包含另一个makefle,并且在我执行此操作时需要正确设置变量)。
答案 0 :(得分:2)
$(call ...)
函数不评估函数的结果,就好像它是makefile代码一样,所以你不能在那里ifdef
之类的东西。
会发生check-var-defined
的内容被扩展,因为它无法识别ifdef
操作,所以每次都会扩展$(error ...)
函数。
如果您想使用ifdef
,则必须使用$(eval ...)
$(call ...)
来评估结果,就好像它是一个makefile一样。
更简单的是使用$(if ...)
函数,如下所示:
check-var-defined = $(if $(1),,$(error $(1) is not defined))
请注意,如果变量为空,则会失败,这与 undefined 不完全相同;它可能被定义为空(如VAR1=
)。但这也是ifdef
的工作方式,令人困惑。
答案 1 :(得分:2)
第一个答案中的宏很棒,但实际上并没有报告“空”的名称。变量。这是使用example / test稍微改进一下:
# -*- mode: makefile -*-
check-var-defined = $(if $(strip $($1)),,$(error "$1" is not defined))
my_def1:=hello
my_def3:=bye
$(call check-var-defined,my_def1)
$(call check-var-defined,my_def2)
$(call check-var-defined,my_def3)
结果:
Makefile:10: * " my_def2"没有定义。停止。
答案 2 :(得分:0)
defined = $(strip $(filter-out undefined,$(flavor $1)))
ensure-defined = \
$(eval .ensure-defined :=) \
$(foreach V,$(sort $1), \
$(if $(call defined,$V),,$(eval .ensure-defined += $V)) \
) \
$(if $(strip ${.ensure-defined}), \
$(foreach V,${.ensure-defined}, \
$(info NOT DEFINED: $$$V) \
) \
$(error Required variables not defined) \
)
ifFOO = $(if $(call defined,FOO), \
$(info FOO is defined: '${FOO}'), \
$(info FOO not defined) \
)
$(ifFOO)
FOO := foo
$(ifFOO)
$(call ensure-defined,FOO BAR)
all: ; @:
输出:
$ make -f foo.mk
FOO not defined
FOO is defined: 'foo'
NOT DEFINED: $BAR
foo.mk:25: *** Required variables not defined. Stop.