问题
I like to use the g++ -MM
feature to auto-build my dependencies. The way I do this is as follows:
include $(ALLOBJ:%.o=%.d)
%.d: %.cxx
@echo making dependencies for $<
@g++ -MM $(CXXFLAGS) $< -o $@
@sed -i 's,$*\.o,& $@ ,g' $@
Basically I can give this rule ALLOBJ
, and it will:
- convert every
.o
name to a.d
name, andinclude
it, - when it can't find a
.d
, it will create it from the.cxx
file- the final line of the
%.d: %.cxx
rule will add the name of the.d
file to the file itself, so that the dependency will be updated automatically.
- the final line of the
The issue arises when I remove a header: the .d
file still expects to find it, and make will get upset when it's not there. One solution is to replace include
with -include
, and to build the dependencies within the compile rule. Unfortunately this requires a dependency generation line for each compile rule, and will also ignore all other include
errors (which seems risky). Is there some other simple way to auto-build dependencies which avoids this issue?
回答1:
To restate my answer to the other question, I do it this way:
%.o: %.cpp
@echo making $@ and dependencies for $< at the same time
@$(CC) -MD -c $(CXXFLAGS) -o $@ $<
@cp $*.d $*.P
@sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.P >> $*.d
@rm $*.P
-include $(ALLOBJ:%.o=%.d)
EDIT:
It... It produces the dependency file, but more cleanly and without the sed
command:
%.o: %.cpp
@echo making $@ and dependencies for $< at the same time
@$(CC) -c $(CXXFLAGS) -o $@ $<
@$(CC) -MM -MP $(CXXFLAGS) $< -o $*.d
-include *.d
So now I have to modify the %.o
rule in my own makefiles. From now on there'll be a little bit of @JackKelly in everything I compile, mocking me. Oh, this is a black day.
回答2:
Reading the g++ manual a bit more, and thanks to @jackKelly and @Beta's responses above, I found the following solution:
include $(ALLOBJ:%.o=%.d)
%.d: %.cxx
@echo making dependencies for $<
@g++ -MM -MP -MT $*.d -MT $*.o $(CXXFLAGS) $< -o $@
To summarize the flags:
-MM
: build dependencies (rather than compiling)-MP
: build 'dummy' targets for all headers. This prevents make from complaining when headers are deleted and thus can't be found.-MT
: specify the targets for the rule. This allows us to tell make the.d
file depends on the headers without resorting to the ugly sed rule.
I don't believe my solution is any more correct than @Beta's solution. I tend to use multiple compile rules for C++ files in the same makefile, so having a single dependency rule for all of them is slightly cleaner (in my case) than generating the dependencies in each compile rule.
来源:https://stackoverflow.com/questions/12867144/to-include-or-include-auto-generated-dependencies