Makefile警告: pattern recipe did not update peer target

标签 makefile warnings gnu-make

背景:

我们有一个位于开发运营管道中间的 Makefile,它以不寻常的方式做事,由于遗留原因不值得描述。这多年来一直运行良好,但在升级到 GNU Make 4.4 后,它开始生成以下形式的新警告:

Makefile:X: warning: pattern recipe did not update peer target 'Y'.

我 99% 确定此警告对我们的用例无害,但新的警告输出会导致我们管道中的 CI 故障。该 Makefile 由自动化脚本调用,输出也由自动化脚本解析,两者都不能轻易更改。

最小再现器:

生成文件:

%-seq %-par :: %.cpp force
        $(MAKE) do_complicated_stuff SRC=$< TGT=$@

do_complicated_stuff:
        @echo doing complicated stuff with SRC=$(SRC) TGT=$(TGT)
        touch $(TGT)

%-seq :: %.c force
        echo Error: this rule should not be run in this MRE
        exit 1

.PHONY: force

命令:

$ rm -f *-{seq,par} ; touch foo.cpp ; make --no-print-directory foo-seq

make do_complicated_stuff SRC=foo.cpp TGT=foo-seq
doing complicated stuff with SRC=foo.cpp TGT=foo-seq
touch foo-seq
Makefile:2: warning: pattern recipe did not update peer target 'foo-par'.

这里make被调用来构建 foo-seq目标,但它提示 foo-par目标不存在,甚至没有被提及。给定make将调用命令一次只构建一个目标,并且 .PHONY dependency 确保规则将运行(无论 Make 是否认为依赖项是最新的)。 Make 将在同一目录中多次调用(由脚本)来构建每个测试。

问题:

为什么 GNU Make 4.4 突然为过去一直默默地正常工作的习惯用法生成这个新警告,以及要消除这个无害警告的最小更改是什么?

限制/要求:

  1. 该解决方案可能需要涉及某种模式规则,因为可能的源文件名集无法在 Makefile 中进行编码。该名称仅在命令行上提供(无法更改),但规则需要将其与源文件的存在进行匹配,以确保选择并执行正确的规则。
  2. 在真实的 Makefile 中,上面建模的两条规则比此处显示的要复杂得多,因此我们希望避免为每个目标模式重复第一条规则(这确实会消除警告,但会导致可维护性问题) .
  3. 最后,出于可移植性的原因,该解决方案需要继续正常运行,并且所有版本的 GNU Make 回到 v3.80 时都不会出现新的警告(如果确实没有更好的解决方案,可能可以协商)。

最佳答案

目前的计划是,在 GNU make 的下一个版本中,这将成为错误而不是警告。所以你现在应该解决这个问题。更改的原因是 GNU make 处理模式的方式存在其他错误,如果不更改此错误就无法修复这些错误。

问题在于这条规则:

%-seq %-par :: %.cpp force
        $(MAKE) do_complicated_stuff SRC=$< TGT=$@

我不确定您打算让这个规则实际做什么,但它告诉 make 它将做的是单次调用此配方将创建两个目标 %-seq %-par。这就是单个规则中的多个模式的含义,并且一直都是这样的含义。

如果您的配方实际上并未构建这两个目标,那么您将看到此问题。

最简单的做法是将规则编写两次,每个目标编写一次,这将适用于所有版本的 GNU make,并且始终是正确的编写方法:

%-seq :: %.cpp force
        $(MAKE) do_complicated_stuff SRC=$< TGT=$@
%-par :: %.cpp force
        $(MAKE) do_complicated_stuff SRC=$< TGT=$@

预计到达时间

想要避免“重复食谱”是很微不足道的。只需将其放入变量即可:

define COMPLEX_RECIPE
    $(MAKE) do_complicated_stuff SRC=$< TGT=$@
endef

%-seq :: %.cpp force ; $(COMPLEX_RECIPE)
%-par :: %.cpp force ; $(COMPLEX_RECIPE)

关于Makefile警告: pattern recipe did not update peer target,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74449959/

相关文章:

具有两个同名目标的 Makefile

ios - 使用 IOS 相机,得到 <wait_fences : failed to receive reply: 10004003>

python - 如何禁用仅在将 .py 转换为 .exe 后才显示的 python 警告?

java - 如何解决 "static method ___ should be accessed in a static way"警告

linux - 对目录中的文件使用 rm

makefile - 生成文件中的 Shell 条件

makefile - GNU 默认静音

makefile - makefile 中的 "$(@:%.o=%.d)"是什么意思?

cygwin - 有人用MinGW/MSYS成功编译了freetype吗?

linux - 如何实现这个功能呢? (这个功能的名字是什么?)