简体   繁体   English

Makefile 单个目标的多个依赖行?

[英]Makefile multiple dependency lines for a single target?

To generate dependency files I can use something like this to generate dependency files:要生成依赖文件,我可以使用类似这样的东西来生成依赖文件:

-include $(patsubst %.cpp,build/%.d,$(SRC))
build/%.o: %.cpp
    $(CC) $(CXXFLAGS) -c -o $@ $<
    $(CC) $(CXXFLAGS) -MM -MT $@ -MF $(patsubst %.o,%.d,%@) $<

This generates everything and puts both the object and dependency files into the build dir where I want them.这会生成所有内容并将 object 和依赖文件放入我想要的构建目录中。 But this makes two dependency lines for the <file>.o targets, one from the -include rule and with all the header dependencies, and one which is from the pattern rule.但这为<file>.o目标创建了两条依赖线,一条来自-include规则和所有 header 依赖关系,一条来自模式规则。 Will this get interpreted correctly, ie when a header is modified, the object will be recompiled via the command specified for the pattern rule?这是否会得到正确解释,即当修改 header 时,将通过为模式规则指定的命令重新编译 object?

Edit: So this approach does in fact work quite well.编辑:所以这种方法实际上效果很好。 I guess I'd like somebody to provide an answer which gives me some insight into what it is exactly that make does in these situations.我想我希望有人能提供一个答案,让我深入了解make在这些情况下究竟做了什么。 For instance, what if a different command was given for both rules for the same target?例如,如果对同一目标的两条规则给出不同的命令怎么办? My guess would be that it gives an error since it wouldn't be obvious which command to execute.我的猜测是它会给出一个错误,因为执行哪个命令并不明显。

You should add one more pattern rule to express the dependency between the .cpp and .d files and use that rule to create the .d files (second line in the pattern rule of your question) instead of creating the .d files unconditionally.您应该再添加一个模式规则来表达.cpp.d文件之间的依赖关系,并使用规则来创建.d文件(您问题的模式规则中的第二行),而不是无条件地创建.d文件。 It might make sense to introduce another dependency between all .h and .cpp files and all .d files to force re-creating the .d files if a header or source file changes.如果 header 或源文件发生更改,则在所有.h.cpp文件以及所有.d文件之间引入另一个依赖项以强制重新创建.d文件可能是有意义的。

Here's the separate rule for.d files (hope I got it right):这是 .d 文件的单独规则(希望我做对了):

-include $(patsubst %.cpp,build/%.d,$(SRC))
build/%.o: %.cpp
    $(CC) $(CXXFLAGS) -c -o $@ $<

build/%.d: %.cpp
    $(CC) $(CXXFLAGS) -MM -MT $@ -MF $<

Edit: So this approach does in fact work quite well.编辑:所以这种方法实际上效果很好。 I guess I'd like somebody to provide an answer which gives me some insight into what it is exactly that make does in these situations.我想我希望有人能提供一个答案,让我深入了解 make 在这些情况下究竟做了什么。

I'm afraid currently it would only work by chance (or you have not given all relevant pieces from the make file).恐怕目前它只会偶然起作用(或者您没有提供make文件中的所有相关部分)。 See, you have not expressed any dependency between .d files and .cpp files.看,你没有表达.d文件和.cpp文件之间的任何依赖关系。 This, however, is needed so that your .d files get updated before inclusion as make file fragment.但是,这是必需的,以便您的.d文件在包含为 make 文件片段之前得到更新。

For instance, what if a different command was given for both rules for the same target?例如,如果对同一目标的两条规则给出不同的命令怎么办? My guess would be that it gives an error since it wouldn't be obvious which command to execute.我的猜测是它会给出一个错误,因为执行哪个命令并不明显。

With that syntax it wouldn't make a difference.使用这种语法,它不会有所作为。 But there are some special cases where splitting the rules into two (though otherwise identical rules) has merit.但是在某些特殊情况下,将规则一分为二(尽管其他规则相同)是有好处的。 I strongly recommend you get the book "Managing Projects with GNU Make" to get a grip on the various ways of working with GNU Make.我强烈建议您阅读“使用 GNU Make 管理项目”一书,以掌握使用 GNU Make 的各种方式。 The only other recommendation in connection with GNU Make is to read to read the paper here .与 GNU Make 相关的唯一其他建议是阅读此处的论文

Yes, you can specify several rules for one file, and they get merged into one.是的,您可以为一个文件指定多个规则,并将它们合并为一个。 See the GNU Make documentation .请参阅GNU Make 文档

[...] There can only be one recipe to be executed for a file. [...] 一个文件只能执行一个配方。 [...] An extra rule with just prerequisites can be used to give a few extra prerequisites to many files at once. [...] 一个只有先决条件的额外规则可用于一次为许多文件提供一些额外的先决条件。

And I second that there should be separate rule for .d files.我认为.d文件应该有单独的规则。 It's names in many projects are deps or depend .它在许多项目中的名称是depsdepend

POSIX 7 also says that multiple lines for a given target work http://pubs.opengroup.org/onlinepubs/9699919799/ POSIX 7还表示给定目标的多行工作http://pubs.opengroup.org/onlinepubs/9699919799/

A target that has prerequisites, but does not have any commands, can be used to add to the prerequisite list for that target.具有先决条件但没有任何命令的目标可用于添加到该目标的先决条件列表。 Only one target rule for any given target can contain commands.任何给定目标只有一个目标规则可以包含命令。

so long as only one has the commands.只要只有一个人有命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM