Makefile 使忽略的前提条件不';不存在
Makefile 使忽略的前提条件不';不存在,makefile,gnu-make,Makefile,Gnu Make,make继续构建,并表示当我的依赖项文件表示对象依赖于已移动的头文件时,所有内容都是最新的 如果运行make-d捕获我看到的评估: Considering target file `../build/out/src/manager.o'. Looking for an implicit rule for `../build/out/src/manager.o'. No implicit rule found for `../build/out/src/manager.o'.
make
继续构建,并表示当我的依赖项文件表示对象依赖于已移动的头文件时,所有内容都是最新的
如果运行make-d
捕获我看到的评估:
Considering target file `../build/out/src/manager.o'.
Looking for an implicit rule for `../build/out/src/manager.o'.
No implicit rule found for `../build/out/src/manager.o'.
Pruning file `../product/build/config/product.conf'.
Pruning file `../build/out/opt_cc.txt'.
Considering target file `../mem/src/manager.c'.
Looking for an implicit rule for `../mem/src/manager.c'.
No implicit rule found for `../mem/src/manager.c'.
Finished prerequisites of target file `../mem/src/manager.c'.
No need to remake target `../mem/src/manager.c'.
Pruning file `../mem/mem.h'.
Finished prerequisites of target file `../build/out/src/manager.o'.
Prerequisite `../product/build/config/product.conf' is older than target `../build/out/src/manager.o'.
Prerequisite `../build/out/opt_cc.txt' is older than target `../build/out/src/manager.o'.
Prerequisite `../mem/src/manager.c' is older than target `../build/out/src/manager.o'.
Prerequisite `../mem/mem.h' of target `../build/out/src/manager.o' does not exist.
../build/out/src/manager.o'.
Prerequisite `../mem/mem_in.h' is older than target `../build/out/src/manager.o'.
No need to remake target `../build/out/src/manager.o'.
因此make知道该文件是需要的,并且不在那里,但不会尝试根据规则创建该文件,否则将失败
Prerequisite `../mem/mem.h' of target `../build/out/src/manager.o' does not exist.
这是为什么?我如何才能让make不忽略此规则?很可能您已经实现了一种自动依赖项生成方法,该方法告诉make在不存在这些文件的情况下,通过在没有规则的情况下为该文件定义目标,从根本上忽略这些文件。当我有这个makefile时:
foo: foo.h ; @echo make $@ from $^
foo: foo.h ; @echo make $@ from $^
foo.h:
没有foo.h
make告诉我:
$ make
make: **** No rule to make target 'foo.h', needed by 'foo'. Stop.
但是,如果我有这个makefile:
foo: foo.h ; @echo make $@ from $^
foo: foo.h ; @echo make $@ from $^
foo.h:
现在,make非常高兴:
$ make
make foo from foo.h
这是许多自动依赖项生成实用程序所依赖的有文档记录的行为:如果查看生成的依赖项生成文件,您将看到每个头文件的一个空目标
其思想是,给定正确的依赖关系信息,在不修改其他源文件或头文件的情况下,决不能重命名或删除头文件,这将导致无论如何都要重建对象文件(因此下次正确地重新创建依赖关系信息).我发现的修复方法是使用静态模式规则而不是模式规则。模式规则如下所示:
%.o : %.c
*recipe here*
$(OBJECTS): %.o: %.c
*recipe here*
静态模式规则仅适用于目标文件的显式列表,如下所示:
%.o : %.c
*recipe here*
$(OBJECTS): %.o: %.c
*recipe here*
其中变量OBJECTS
在makefile的前面定义为目标文件列表(用空格分隔),例如:
OBJECTS := src/fileA.c src/fileB.c src/fileC.c
请注意,您可以使用各种make
实用程序函数来构建目标文件列表。例如,$(通配符模式)
,$(addsuffix)
,等等
您没有显示makefile的相关部分,因此我不能确定这是否能解决您的问题。但是我得到了同样的症状,即make
忽略不存在的先决条件,来自make-d
的关于“先决条件不存在”的相同消息,但是make
没有创建先决条件
请注意,make
包含大约90个内置隐式规则,其中大多数是模式规则。因此,即使您的makefile没有模式规则,这仍然会影响您
我注意到一些事情:
make
知道如何构建先决条件make
的行为是如何不同的make-r
关闭隐式规则数据库没有帮助make
关于不需要构建先决条件来构建目标的说法可能是正确的。如果你只是要求建立目标,那么make会尽可能少地完成
它看起来仍然像是make
中的一个bug。但这可能只是我的错误理解,我不是专家
更新:(2016年3月16日)。我目前的理解是make
将这些必备文件视为中间文件,因此不关心在目标文件已经存在时创建它们Make
将中间文件视为“二级公民”,它仅在创建“一级公民”(makefile中定义的明确目标)或命令行上作为Make
参数请求的目标时才创建中间文件
通过使用静态模式规则(而不是模式规则),这些文件现在被列为显式目标,因此不是中间文件,而是“第一类公民”,在必要时创建和更新
顺便说一句,这也解释了为什么在没有先决条件的情况下使用
.SECONDARY
没有帮助。这样做可以防止删除中间文件,但它们仍然被视为中间文件,因此除非需要创建目标或目标,否则不会创建它们。我在代码库中对此问题研究了很长时间,但找不到与我的情况相匹配的任何原因(或解决方案)(不管我在这个主题上搜索了多少次)。@owler在“Update:(2016年3月16日)”附录中,提供了一个关于“使用.SECONDARY
不带任何先决条件”语句实际问题的提示防止删除中间文件,但它们仍被视为中间文件,因此make不会创建它们,除非需要它们来创建目标。”
实际上,“中间”文件还有一个额外的特性,它实际上导致了我遇到的问题
以下是makefile的外观:
.SECONDARY:
x.exe: x.o
$(RECIPESTEP1)
x.o: x.c
$(RECIPESTEP2)
在我的例子中,x.o是没有被重建的目标(即使它被明确列为make goal x.exe的依赖项)。更重要的是(为了理解这个问题),x.exe已经存在
“中间”目标的完整行为描述是,仅当需要“中间”目标来构建从属目标时,才会构建“中间”目标。如果必须重建“中间”目标的从属关系,则才会构建“中间”目标。在我的例子中,“x.c”文件