首页 > 解决方案 > 没有目标的 Makefile 规则

问题描述

我正在调试一个makefile,并在宏扩展中创建一个没有目标的规则(如下所示:)

: | directoryA
    @echo running $@
    ...

我在网上查了一下,makefile 文档似乎暗示(但没有明确说明)应该至少有一个目标。

使用我当前的 make 版本(gnu Make 4.2.1),它并没有杀死我,但我只是想知道这是否被认为是未定义的行为或者是否支持,如果是,它应该做什么。

标签: makefilegnu-make

解决方案


我在网上查了一下,makefile 文档似乎暗示(但没有明确说明)应该至少有一个目标。

不同make的 s 可能表现不同。根据 makefile 的内容,它们甚至可能表现出对特定 makefile 语法问题的变体处理——例如,如果 makefile 以.POSIX:特殊目标的规则开头,则其解释可能与没有该规则的相同 makefile 的解释不同。

然而,总的来说,如果您想对什么应该被认为是正确的有某种总体概念,那么POSIX 标准的定义make是一个相当好的基线。它说:

目标规则的格式如下:

target [target...]: [prerequisite...][;command]
[<tab>command<tab>command...]

line that does not begin with <tab>

目标条目由 <blank> 分隔的非空目标列表指定,然后是 <colon>, [...]

(强调补充)。它还继续说

应用程序应从可移植字符集中仅由句点、下划线、数字和字母组成的字符集中选择目标名称

, 从中我们可以推断出语法描述是在宏扩展之后讨论规则文本,因为宏引用可以出现在规则的目标列表中(或根据规范在 makefile 中的任何位置),但是字符$, (, ), {, 并且}出现在宏引用中不属于可以出现在目标中的那些。

makefile 预期内容的规范确实明确指出目标列表是非空的,并且在您的特定make文档不覆盖它的情况下将其视为权威是合理的。

我只是想知道 [一个空的目标列表] 是否被认为是未定义的行为,或者这是否受支持

您的 makefile 和运行时宏值的组合不符合 POSIX 的要求make。规范没有定义在这种情况下应该发生什么,所以从这个意义上说,行为是未定义的,但“未定义的行为”在这个领域并不像在 C 和 C++ 语言规范中那样强大。

鉴于此,我认为任何规则的目标列表为空(在宏扩展之后)是一个 makefile 缺陷。尽管make您当前使用的可能会毫无怨言地接受它,但其他人make,包括您现在的未来版本make,可能会拒绝它或更糟。


推荐阅读