Having to deal with dependencies in Makefile is a real pain, there are a lot of examples of way to deal with it on the web but none of them is satisfying.
For example using
gcc -MM does not work with subfolders, a
depend rule requires the user to use it everytimes he adds new files ...
Here is what is wanted:
- Completly automatic: No user interaction is required when adding new files
- Works with an arbitrary amount of files
- Works with an arbitrary amount of level of folders
- Is not recalculated when nothing changed
- Use only one file to store dependencies
- Do not depend on complicated regular expressions
Here is the result:
BINARY = project.exe CC = gcc CFLAGS = FILES = $(shell find src/ -name "*.c") HEADERS = $(shell find src/ -name "*.h") OBJS = $(FILES:.c=.o) all: $(BINARY) -include Makefile.deps $(BINARY): Makefile.deps $(OBJS) $(CC) $(CFLAGS) $(OBJS) -o $(BINARY) Makefile.deps: $(FILES) $(HEADERS) makedepend -- $(CFLAGS) -- $(FILES) -f- > Makefile.deps
This is in fact really easy. In your
$(BINARY) rule, you add
Makefile.deps as a prerequisite.
In order to generate the
Makefile.deps you mark all
$(HEADERS) as prerequisite, so every time you change a file or header it will recompile the list.
We use makedepend to generate the dependencies list. It works like
gcc -MM except that it outputs the correct file path when used with folders.
Then all is required is to include the
Makefile.deps. We include it with
-include so it does work the first time you compile.
Thanks to Lemoine Gauthier who helped me to discover this technique.