How can I have a Makefile automatically rebuild source files that include a modified header file? (In C/C++)

As already pointed out elsewhere on this site, see this page: Auto-Dependency Generation

In short, gcc can automatically create .d dependency files for you, which are mini makefile fragments containing the dependencies of the .c file you compiled. Every time you change the .c file and compile it, the .d file will be updated.

Besides adding the -M flag to gcc, you'll need to include the .d files in the makefile (like Chris wrote above). There are some more complicated issues in the page which are solved using sed, but you can ignore them and do a "make clean" to clear away the .d files whenever make complains about not being able to build a header file that no longer exists.


You could add a 'make depend' command as others have stated but why not get gcc to create dependencies and compile at the same time:

DEPS := $(COBJS:.o=.d)

-include $(DEPS)

%.o: %.c
    $(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$@) -o $@ $<

The '-MF' parameter specifies a file to store the dependencies in.

The dash at the start of '-include' tells Make to continue when the .d file doesn't exist (e.g. on first compilation).

Note there seems to be a bug in gcc regarding the -o option. If you set the object filename to say obj/_file__c.o then the generated _file_.d will still contain _file_.o, not obj/_file_c.o.


This is equivalent to Chris Dodd's answer, but uses a different naming convention (and coincidentally doesn't require the sed magic. Copied from a later duplicate.


If you are using a GNU compiler, the compiler can assemble a list of dependencies for you. Makefile fragment:

depend: .depend

.depend: $(SOURCES)
        rm -f ./.depend
        $(CC) $(CFLAGS) -MM $^>>./.depend;

include .depend

There is also the tool makedepend, but I never liked it as much as gcc -MM


You'll have to make individual targets for each C file, and then list the header file as a dependency. You can still use your generic targets, and just place the .h dependencies afterwards, like so:

%.o: %.c
        @echo Compiling $<...
        $(CC) $(CFLAGS) -c -o $@ $<

foo.c: bar.h
# And so on...

Basically, you need to dynamically create the makefile rules to rebuild the object files when the header files change. If you use gcc and gnumake, this is fairly easy; just put something like:

$(OBJDIR)/%.d: %.c
        $(CC) -MM -MG $(CPPFLAGS) $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >$@

ifneq ($(MAKECMDGOALS),clean)
include $(SRCS:%.c=$(OBJDIR)/%.d)
endif

in your makefile.