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. 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. Will this get interpreted correctly, i.e. when a header is modified, the object will be recompiled via the command specified for the pattern rule?
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. 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. 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.
Here's the separate rule for .d files (hope I got it right):
-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.
I'm afraid currently it would only work by chance (or you have not given all relevant pieces from the make file). See, you have not expressed any dependency between .d
files and .cpp
files. This, however, is needed so that your .d
files get updated before inclusion as make file fragment.
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. The only other recommendation in connection with GNU Make is to read to read the paper here.
Yes, you can specify several rules for one file, and they get merged into one. See the GNU Make documentation.
[...] 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. It's names in many projects are deps
or depend
.
POSIX 7 also says that multiple lines for a given target work 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.
精彩评论