当依赖关系列表更改时,重新链接Makefile目标 [英] Relink Makefile target when list of dependencies changes

查看:195
本文介绍了当依赖关系列表更改时,重新链接Makefile目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Makefile中看到的一个常见问题是,当依赖项列表发生变化时,可执行文件(和库)就不一定重新链接。例如:

  SRCS = $(通配符* .c)
CPPFLAGS = -MMD -MP
目标:$(SRCS:.c = .o)
$(CC)$(LDFLAGS)$ ^ -o $ @
-include $(SRCS:.c = .d)
到目前为止,它很好:它可以自动处理源文件及其附带的依赖关系的任何更改。

如果添加了一个文件(因为通配符,这意味着只需将其添加到目录中,但显式列表将具有相同的问题),请看到并重新链接目标。但是,当一个源文件被删除时,make不知道目标是否需要重建。



如何获取make(gmake,具体来说)来处理这个情况?



诚然,这不是一个常见的情况,因为删除文件很可能意味着其他文件也必须更改,然后强制重新链接,但是我以前看过它。



我已经提出了两个解决方案,这两个都不是理想的。首先,如果我们使源列表显式而不是通配符,我们可以使目标依赖于Makefile。更改Makefile以删除源文件,然后使目标重新链接。这有两个问题。首先,你必须在链接之前从$ ^中删除Makefile,这是一个有点丑陋(但是可以过滤掉)。第二,这个Makefile是一个模板,由其他Makefile(它们指定源代码和目标)所包含) - 我们必须使目标依赖于 Makefile。



第二个解决方案是包含一些如下所示的逻辑:

  SRCS = $(通配符* .c)
CPPFLAGS = -MMD -MP
target:$(SRCS:.c = .o)
$(CC)$(LDFLAGS) $ ^ -o $ @
@echo'$$(如果$$(filter-out $$(SRCS:.c = .o),$(SRCS:.c = .o)),.PHONY:目标)'> target.d
-include $(SRCS:.c = .d)
-include target.d

这将创建一个跟踪依赖关系列表的目标文件,并强制目标重建,如果删除任何内容。它的作品,但它是丑陋的。它也不能解释包括Makefile指定的任何其他非源依赖性。



有没有正式的方法来做,或至少更好的方法?



(除此之外,我还要清除源文件被删除时的关联对象和依赖关系文件,如果可能的话,这可能是通过扩展我的第二个解决方案,使其变得更加丑陋。)

解决方案

要正确执行,您可能需要诉诸 Paul Smith的高级自动相关生成。保罗是目前GNU的维护者,并描述了关于依赖生成的所有常见问题(及其解决方案)。



他网站上的其他白皮书是推荐。



我几年来使用他的技巧和技巧,即使偶尔会变得复杂一些 - 研究它们是值得的。 / p>

A common problem I've seen with Makefiles is that executables (and libraries, for that matter) aren't necessarily relinked when the list of dependencies changes. For example:

SRCS=$(wildcard *.c)
CPPFLAGS=-MMD -MP
target: $(SRCS:.c=.o)
        $(CC) $(LDFLAGS) $^ -o $@
-include $(SRCS:.c=.d)

So far, so good: it automatically handles any changes to source files and their included dependencies. If a file is added (because of the wildcard, that means just adding it to the directory, but an explicit list would have the same problem), make sees it and relinks the target. However, when a source file is removed, make doesn't know that the target needs to be rebuilt.

How do I get make (gmake, specifically) to handle this situation?

Admittedly, it's not exactly a common situation, as removing a file will most likely mean that other files must be changed too, which would then force a relink anyway, but I've seen it happen before.

I've come up with two solutions, neither of which is ideal. First, if we make the source list explicit instead of wildcarded, we can make the target depend on the Makefile. Changing the Makefile to remove a source file then causes the target to be relinked. This has two problems. First, you have to strip out Makefile from $^ before linking, which is a bit ugly (but do-able with filter-out). Second, this Makefile is intended to be a template, included by other Makefiles (which specify the sources and the target) -- we have to make the target depend on that Makefile instead. Ugh.

The second solution is to include some logic like the following:

SRCS=$(wildcard *.c)
CPPFLAGS=-MMD -MP
target: $(SRCS:.c=.o)
        $(CC) $(LDFLAGS) $^ -o $@
        @echo '$$(if $$(filter-out $$(SRCS:.c=.o), $(SRCS:.c=.o)), .PHONY:target)' > target.d
-include $(SRCS:.c=.d)
-include target.d

This makes a target.d file that tracks the list of dependencies and forces the target to be rebuilt if anything is removed. It works, but it's ugly. It also can't account for any additional non-source dependencies specified by an including Makefile.

Is there an official way to do this, or at least a better way?

(As an aside, I'd also like to clean up the associated object and dependency files when the source file is removed, if possible. That might be possible by extending my second solution and making it even uglier.)

解决方案

To do it properly, you'll probably have to resort to Paul Smith's Advanced Auto-Dependency Generation. Paul is the current maintainer of GNU make, and has described all the common problems (and their solutions!) concerning dependency generation.

The other white-papers on his website are recommended as well.

I use his tips and tricks for several years now, and - even if it gets complicated a little occasionally - studying them has been worth every second.

这篇关于当依赖关系列表更改时,重新链接Makefile目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆