【问题标题】:Makefile: need to do a target before including another makefileMakefile:在包含另一个makefile之前需要做一个目标
【发布时间】:2011-06-17 07:48:08
【问题描述】:

我的 Makefile 的一部分:

CPUDEPS=./mydeps.cpu
(...)
deps: $(CPUDEPS)

$(CPUDEPS): $(CCFILES)
 @echo [DEPS] CPU
 $(CMDECHO)makedepend -Y -s'# CPU sources dependencies generated with "make deps"' \
  -w4096 -f- -- $(CFLAGS) -- $^ 2> /dev/null > $(CPUDEPS)
(...)
sinclude $(CPUDEPS)

问题 1:包括在第一阶段处理完成,目标在第二阶段完成;所以,如果 ./mydeps.cpu 不存在并且我“制作 deps”,我首先会得到错误

Makefile:335: ./mydeps.cpu: No such file or directory

我使用sinclude 而不是include 隐藏了错误,但问题仍然存在:包含旧文件,而不是刚刚生成的文件。必须运行两次才能包含更新的文件。这是因为 make 进行了两阶段处理;有什么方法可以告诉 make 解析包含之前完成目标 deps?

问题 2:即使文件 ./mydeps.cpu 不存在并且 make deps 实际创建了它,我总是得到一个“make: Nothing to do for deps”。其他目标不会发生这种情况。我不明白为什么以及如何避免它。

【问题讨论】:

    标签: include dependencies makefile


    【解决方案1】:

    问题 1 不存在:在构建目标之前,make 会自动重新构建 makefile(如果未提供显式规则,则使用隐式规则)。因此,为 makefile 制定规则可确保始终保持最新状态,无需运行 deps 两次。此外,由于CPUDEPS 是一个makefile,它会在运行任何其他规则之前自动更新,因此如果需要,将始终更新依赖关系,并且不需要make deps。如果CCFILES 中的任何一个变得比依赖文件更新,您可能会通过观察[DEPS] 行被回显来自己注意到这一点。

    对于问题 2,向配方中添加任何内容可确保 make 不会抱怨无事可做。如果没有其他内容,您可以使用 @echo OK 之类的东西向用户提供反馈,或者如果您更喜欢完全无声的制作,则可以使用简单的 @true

    【讨论】:

      【解决方案2】:

      您试图实现的目标是无用的:您可以使用在先前构建期间创建的依赖文件。够了。

      该规则背后的主要原因是:

      • 如果您没有更改任何文件,则依赖项文件是最新的,无需构建任何内容。
      • 如果您在先前构建使用的现有文件上更改了任何内容,甚至非常深入到您的#include 链,那么依赖文件已经捕获了它。您将重建所需的内容。
      • 如果您更改了新文件中的某些内容(您添加了该文件!),那么以前的构建没有使用它,并且没有在依赖项中列出。但是如果你真的想使用它,那么你必须至少修改一个之前使用过的其他文件,然后你又回到了以前的情况。

      解决方案是在编译的正常过程中创建依赖文件,如果存在,可以选择包含它(使用sinclude)。

      【讨论】:

      • 这“解决”了问题 1 在更新依赖项的情况下,但是否有可能为一般目的实现这样的机制? (我的意思是:包括一个刚刚生成的文件)。
      猜你喜欢
      • 2013-10-18
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      相关资源
      最近更新 更多