【问题标题】:Makefile : last resort match anything patternMakefile:最后的手段匹配任何模式
【发布时间】:2018-02-15 13:58:22
【问题描述】:

根据GNU make guide,“您编写的规则优先于那些内置的规则。但是请注意,其先决条件实际存在或被提及的规则始终优先于具有先决条件的规则必须由链接其他隐式规则。”

所以我写了这个测试makefile来做一个小实验(GNUmakefile是这个测试makefile的名字):

% :: 
        @echo "last resort implicit rule is working"

.DEFAULT_GOAL = src/hello.o

src/hello.o : 
GNUmakefile : ;#used to prevent remaking this makefile, although in this case it is unnecessary.

我的文件组织如下图所示:

GNUmakefile(#ordinary file)

src(#directory)
    ----hello.c(#ordinary file)

我期待它输出"last resort implicit rule is working",因为src/hello.o 将匹配目标模式% ::,这是一个终端匹配任何隐含规则。根据GNU make guide 中指定的隐式规则搜索算法,应该应用此规则。

但是,当我运行 make 时,它会输出 cc -c -o src/hello.o src/hello.c

我发现实际上src/hello.o 与内置的隐式规则匹配。当我运行 make -r 时,它会输出 "last resort implicit rule is working"make -d 的输出证明了这一点。

但我认为这种行为与 GUN make 指南中的规定相矛盾。 有人可以帮忙吗?

顺便说一句,我在GUN make guide 中阅读了最后的手段规则,它说“因此,这样的规则的配方用于所有没有自己的配方并且没有其他隐式规则适用的目标和先决条件。” .这是我问题的解决方案吗?我对此表示怀疑,因为我认为这取决于是否定义了最后手段规则以及最后手段规则的定义位置,因为在使用GNU make guide 中指定的算法搜索隐式规则时,顺序很重要。

【问题讨论】:

  • 评论:有时不止一个目标模式与目标匹配,GNU make 使用“最佳匹配”算法来确定要使用的规则。值得思考的是,如果用户定义的模式规则和内置的隐式规则都匹配目标,将使用哪个规则?在这种情况下,“最佳拟合算法”是否优于“优先”用户定义的模式规则(隐式规则)?
  • 评论2:我仔细阅读了这句话“因此,这样的规则的配方用于所有没有自己的配方并且没有其他隐式规则适用的目标和先决条件。”。 “没有其他”是解决我的问题的关键吗?我不知道这是否是“最佳匹配”算法和“优先”用户定义模式规则之间的问题,或者这只是匹配任何模式规则的最后手段。
  • 一些事情——首先,你可以编辑你的问题,然后把你的cmets放在那里。其次,我听说制定一个包罗万象的规则 (%:) 真的 对较大的 makefile 的性能不利。最好使用.DEFAULT: 目标。

标签: makefile


【解决方案1】:

它适用于我工作场所的一些古老品牌......

[teve@madar mktest]$ tree
.
├── GNUmakefile
└── src
    └── hello.c

1 directory, 2 files
[teve@madar mktest]$ cat GNUmakefile
% ::
        @echo "last resort implicit rule is working"

.DEFAULT_GOAL = src/hello.o

src/hello.o :
GNUmakefile : ;#blablabla
[teve@madar mktest]$ make
last resort implicit rule is working
[teve@madar mktest]$ make --version
GNU Make 3.81
[...]

...而且它不适用于少一步的古老品牌:

[teve@madar mktest]$ make
cc    -c -o src/hello.o src/hello.c
[gergelyc@sauron mktest]$ make --version
GNU Make 3.82
[...]

鉴于当前版本是 4.x,我非常幸运能够拥有这两个带有行为改变的版本。
我试图查看implicitbuiltorderlastmatch 在以 3.82 结尾的changelog 中的出现,但我没有发现任何明显的东西。
顺便说一句,用空的%o : %c 取消内置规则是可行的。

【讨论】:

  • 谢谢!稍后我将尝试这些版本的 GNU make。你的回答提醒我,我的make版本也不支持::=操作。
  • 我的make版本是GNU make 3.8.2 Build for x86_64-redhat-linux-gnu
  • @Han 我的实际上是一样的(x86_64 和 RedHat),只是我没有包括那部分。这也适用于 3.81(即在另一台机器上)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多