使3.82 - 向后不兼容问题?

时间:2015-06-08 17:22:12

标签: makefile gnu-make

尝试使用make 3.82运行一些小的Makefile后,我遇到了一些问题。

错误:

[me@localhost make]$ make
 Makefile:3: *** empty variable name.  Stop.

这适用于make 3.81,但不适用于新的。我知道旧版本有一些向后兼容性。

我有两个Makefile,一个是基本的,另一个是主要的。

这是我的Makebase

define TestFile
ifeq ($$(shell test $(1) $(2) || echo 1),1)
    $$(error $(2) mmm, not found)
endif
endef

define CheckIt
$(eval $(call TestFile,-d,$(1)))
endef

define CheckDir
p := $(foreach d,$1,$(call CheckIt,$d))
endef


define SomeCheck
$(call CheckDir,$(1))
endef

这是我的Makefile

include Makebase

$(call SomeCheck, ~/test/make)

正如我所说,它在make 3.81中运行良好。

任何帮助将不胜感激。 感谢

BR

1 个答案:

答案 0 :(得分:1)

所以,我不知道这是在GNU make 3.81中打算做什么的。正如Etan指出的那样,当我使用GNU make 3.81运行你的makefile时,我得到了这个错误:

make: *** No rule to make target `=', needed by `p'.  Stop.

这是因为call函数无法扩展为变量赋值,因此make将p :=解释为p: =(即目标{{1}前提条件为p)。我不知道这实际上是你想要的。如果你没有看到这个错误,我可以假设是你的makefile中的某个地方,有人宣布了一个目标为=的食谱(呃!!)

在GNU make 3.82中,我看到=消息。原因是GNU使3.82引入了解析器增强功能,这导致了一些向后兼容性。 NEWS文件提供此警告:

  

由于解析器增强,三个向后兼容性问题     存在:首先,包含" ="无法逃脱     反斜杠了。您必须创建一个包含" ="的变量。和     在先决条件中使用该变量。

一个未被注意到的副作用是,在先决条件列表中它之前没有值的等号现在被认为是特定于目标的变量,其中变量名称为空,而之前它被认为是目标,因为它没有满足变量赋值的要求。我不确定这是一个错误......总的来说,我并不喜欢"欺骗"奇数角情况的解析器,所以我实际上更喜欢新的行为。

这整个定义都是虚假的:

empty variable name

为什么呢?因为define CheckDir p := $(foreach d,$1,$(call CheckIt,$d)) endef 用户定义的函数只包含CheckIt语句。但eval语句被扩展,结果由make解析,因此总是扩展为空字符串。因此,整个eval循环扩展为空字符串。因此,即使这被解释为你(显然)意图由make,它也总是简单地扩展为:

foreach

这看起来并不是很有用。如果您将上面的定义更改为:

p :=

然后它将永远有效,你不会看到这些奇怪的问题。

我不打算评论这个makefile一般是多么虚伪...... :)