Gnu make 当先决条件通过带有二次展开的变量给出时,我能说服Make给我一个更好的错误消息吗?

Gnu make 当先决条件通过带有二次展开的变量给出时,我能说服Make给我一个更好的错误消息吗?,gnu-make,Gnu Make,注意: OBJECT_FILES= .PHONY: all all: project.exe .SECONDEXPANSION: %.exe:: $$(OBJECT_FILES); project.exe: OBJECT_FILES += module.o 假设磁盘上不存在module.o(因为我忘了创建它,或者别的什么) 关于为什么我不把project.exe:module.o放在一边(这是一个MCVE!实际上,我在其他地方用$OBJECT\u文件做更多事情)的争论我如何才能得到更好的

注意:

OBJECT_FILES=

.PHONY: all
all: project.exe

.SECONDEXPANSION:
%.exe:: $$(OBJECT_FILES);

project.exe: OBJECT_FILES += module.o
假设磁盘上不存在
module.o
(因为我忘了创建它,或者别的什么)

关于为什么我不把
project.exe:module.o
放在一边(这是一个MCVE!实际上,我在其他地方用
$OBJECT\u文件做更多事情)的争论我如何才能得到更好的诊断

$ make all
make: *** No rule to make target `project.exe', needed by `all'.  Stop.
我更喜欢:

$ make all
make: *** No rule to make target `module.o', needed by `project.exe'.  Stop.
在不从根本上改变我的设计的情况下,Make能做到这一点吗

或者,至少,它为什么要这样做



make必须显示的信息可能会变得相当复杂。这是因为隐式模式规则,make实际上是在一个接一个地尝试每个目标匹配的规则
project.exe
,并且可能有一个不确定的数字。例如,考虑如下:

OBJECT_FILES=

.PHONY: all
all: project.exe

.SECONDEXPANSION:
%.exe:: $$(OBJECT_FILES);
%.exe:: does-not-exist-on-unix;
%.exe:: does-not-exist-on-amiga;
%.exe:: does-not-exist-except-perhaps-by-redmond;

project.exe: OBJECT_FILES += does-not-exist
使用
make
-dr
选项,我们可以得到以下结果:

  Considering target file 'project.exe'.
   File 'project.exe' does not exist.
   Looking for an implicit rule for 'project.exe'.
   Trying pattern rule with stem 'project'.
   Trying implicit prerequisite 'does-not-exist'.
   Trying pattern rule with stem 'project'.
   Trying rule prerequisite 'does-not-exist-on-unix'.
   Trying pattern rule with stem 'project'.
   Trying rule prerequisite 'does-not-exist-on-amiga'.
   Trying pattern rule with stem 'project'.
   Trying rule prerequisite 'does-not-exist-except-perhaps-by-redmond'.
   No implicit rule found for 'project.exe'.
Trying implicit premission“not exist”
是“最佳”方式,make会告诉您尝试了第一个模式规则(对象_文件的二次扩展)的先决条件

此外,如果发现任何规则的先决条件,则不会得到任何错误消息:make只允许隐式模式规则“静默”失败,如果不禁用内置规则,这种情况实际上会发生很多。例如,内置规则可以从几种类型的源文件中生成一个对象文件(.o目标),如.cpp(C++)、.C(C)、.p(Pascal)、.f(Fortran)。。。因此,根据实际存在的源文件,将选择正确的规则,而其他规则将以静默方式“删除”。如果您同时拥有.c和.cpp文件,我不知道会发生什么

如果您可以重写makefile,使其不再具有模式规则,例如:

OBJECT_FILES=
EXE_FILES := project.exe project2.exe

.PHONY: all
all: $(EXE_FILES)

.SECONDEXPANSION:
$(EXE_FILES):: $$(OBJECT_FILES);

project.exe: OBJECT_FILES += does-not-exist
project2.exe: OBJECT_FILES += does-not-exist-either
然后make将输出您想要的消息(尽管不是按预期的顺序):

$make-k all

make: *** No rule to make target 'does-not-exist-either', needed by 'project2.exe'.
make: Target 'project2.exe' not remade because of errors.
make: *** No rule to make target 'does-not-exist', needed by 'project.exe'.
make: Target 'all' not remade because of errors.
make: *** No rule to make target 'does-not-exist-either', needed by 'project2.exe'.
make: Target 'project2.exe' not remade because of errors.
make: *** No rule to make target 'does-not-exist', needed by 'project.exe'.
make: Target 'all' not remade because of errors.