GNU make中多行变量声明的区别

28

我读了这个问题,很惊讶它没能运行:

为什么GNU Make的简化命令不起作用?

所以我自己尝试了一下,并得到了相同的结果。这是一个示例makefile:

define foo
bar
baz
endef

define bar = 
foo
baz
endef

$(info foo: $(foo))
$(info bar: $(bar))

all:

下面是运行它的输出:

$ make
foo: bar
baz
bar: 
make: Nothing to be done for `all'.
这里发生了什么?根据GNU make手册,这两个变量声明应该是相同的,我错过了什么吗?
编辑:
以下是我参考的一些手册引用:

3.7 如何读取Makefile文件

define immediate
  deferred
endef

define immediate =
  deferred
endef

5.8 定义罐头食谱

下面是定义罐头食谱的一个例子:

 define run-yacc =
 yacc $(firstword $^)
 mv y.tab.c $@
 endef

6.8 定义多行变量

您可以省略变量赋值运算符。如果省略,则make认为它是“=”并创建递归展开的变量...

正如您所看到的,预定义配方部分明确使用了“=”。 我正在使用GNU Make 3.81。


1
刚遇到了完全相同的问题,而且 apt-get upgrade ; apt-get install make 告诉我 v3.81 是最新版本,所以我越来越生气了...非常感谢! - j_random_hacker
2个回答

30

根据3.82版本的CHANGELOG:

* read.c (do_define): Modify to allow assignment tokens (=, :=, etc.)
after a define, to create variables with those flavors.

在使用define语句之前,好像不支持使用'='。


最佳答案!权威来源的简明引用,恰好解释了观察到的行为。这正是我所寻找的。 - A. Levy

18

很可能是您的make版本问题。我在我的机器上使用Cygwin和make 3.81测试了该makefile,并获得了以下结果:

$ make
foo: bar
baz
bar: 
make: Nothing to be done for `all'.

我使用make 3.82(本地Windows版本)测试了相同的Makefile,得到了以下输出:

C:\>C:\make\make.exe
foo: bar
baz
bar: foo
baz
make: Nothing to be done for `all'.

我认为在线的make手册是针对v3.82版本的。


那是一个简单的解决方案 - 感谢指出我的错误! - Carl Norum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接