Makefile 中包含的依赖文件是如何解析的
我有几个关于 makefile 的问题。 我通过在代码中创建依赖文件 (.d) 来定义我自己的版本,并将其称为 .dd (看起来就像普通的 .c 依赖文件,只是这是针对某些内部文件格式的)。 现在我已使用 include 语句将该文件包含在 makefile 中。 (这些文件有一大堆,所以我将其定义为使用 subst 来根据需要替换扩展名的规则。)
现在假设文件 X 依赖于文件 Y,即 X.dd 包含对文件 Y 的引用。现在根据我的理解,每当我运行 make 并且程序通过包含并发现 Y 已更新时,它会以某种方式重新编译它以反映 X 中的更改。
我的问题是当注意到 Y 中的时间戳更改时,确实会自行重新启动以包含更改。 此类依赖文件到底是如何解析的。 此外,文件 X 不是典型的 .c 或 .cc 文件。 那么当文件的依赖关系发生变化时,将如何处理该文件。
我面临的问题是,如果文件 Y 被更改/触及,文件 X 不会重新编译。 另外,如果我触摸文件 X,它会重新编译得很好。 同样正如预期的那样,如果修改了 makefile,所有内容都会适当地重新编译。
这个错误让我挠头好几天了,所以任何帮助都将不胜感激。
I have a few questions about makefiles. I have defined my own version of a dependency file (.d) by creating it in code and called it say .dd (Looks just like a normal .c dependency file except that this is for some internal file format). Now this file I have included in the makefile with the include statement. (There are a whole bunch of these files so I've defined this as a rule which uses subst to replace the extension as required.)
Now suppose that file X depends on file Y i.e. X.dd contains a reference to file Y. Now from my understanding, whenever I run make and the program goes through the include and finds that Y has been updated, it somehow recompiles this so as to reflect the changes in X.
My question and problem is when this timestamp change in Y is noticed, does make restart itself so as to include the changes. How exactly are dependency files of this sort resolved. Also file X is not a typical .c or .cc file. So how would the file be treated when its dependency changes.
The problem I'm facing is that if file Y is changed/touched, file X does not recompile. Also if I touch file X, it recompiles just fine. Also as expected, if the makefile is touched, everything recompiles appopriately.
This bug has me scratching my head for a few days now so any help whatsoever would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设 X.boy 是从 X.src 生成的(Y.boy 是从 Y.src 生成的),然后进行以下工作:
Makefile:
全部: X.boy Y.boy
X.dd:
X.boy: Y.src
然后给出:
Presuming that an X.boy is generated from an X.src (and Y.boy from Y.src) then to following works:
Makefile:
all: X.boy Y.boy
X.dd:
X.boy: Y.src
This then gives:
GNU make 在启动时读取文件的时间戳一次。 如果您没有明确地重新调用它(例如,通过从 makefile 中调用 make 或 $MAKE),它不会在运行命令后重新检查时间戳。
所有文件都受到相同的处理; make 对于某些类型的文件只有一些内置规则。 对于所有文件类型,依赖性的处理方式相同。
听起来您包含的 .d 文件正在创建对源文件而不是目标文件的依赖关系。 您可以通过使用
make -p
打印 make 所使用的规则来验证这一点。我将使用 c 文件作为示例,因为您已经知道它们的依赖项应该如何工作。 假设您有一个文件 foo.c(源),它被编译为 foo.o(目标),并且在 foo.d 中指定了其依赖项。 对于这个例子,假设如果 bar.h 或 baz.h 发生变化,我们希望重建 foo.o。
然后 foo.d 应该包含类似以下内容:
你的 makefile 会读取
你的症状听起来像是你有一个 foo.d 包含:
或者在左侧完全不相关的东西,这样 make 不会看到对 foo.o 的依赖。 如果运行 make -p 并在输出中搜索 foo.o,您将看到 make 认为它依赖于 makefile 内容。
GNU make reads the timestamps of files once, when it starts up. If you don't explicitly re-invoke it (e.g. by calling make or $MAKE from within the makefile), it won't re-check the timestamps after running commands.
All files are treated identically; make just has a few built in rules for some types of files. Dependencies are handled the same way for all file types.
It sounds like your included .d file is creating a dependency on the source file(s), and not the target file. You can verify this by printing the rules make is using with
make -p
.I'll use c files as an example, since you already know how their dependencies should work. Lets assume you have a file foo.c (source) which gets compiled to foo.o (target) and whos dependencies are specified in foo.d. For this example, lets say if bar.h or baz.h change, we want foo.o to be rebuilt.
foo.d should then contain something like:
And your makefile would read
Your symptoms sound like you have instead got a foo.d containing:
Or something totally unrelated on the left hand side, such that make does not see a dependency on foo.o. If you run
make -p
and search for foo.o in the output, you will see what make thinks it depends on from your makefile contents.