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
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 $(FILES) and $(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.

If you liked this article, you might be interested in my Twitter feed as well.

Related Posts

  • July 26, 2012 CSS – Cross Browser Drag Cursor (5)
    grab and grabbing are two great CSS cursors you can use when you are moving things around. Windows: Mac: Since those are not standard, it is really tricky to get them working cross browser. This article is going to show you all the available workarounds to get the best version […]
  • September 24, 2011 Javascript: Cyclic Object Detection (13)
    URLON.stringify() suffer from a problem, when passed an object that contains a cycle, it will never stop. This article shows 3 techniques in order to detect if an object is cyclical. Edit the object: Mark In order to detect a cycle in an object, the method we learn at school is to […]
  • September 25, 2011 Javascript Object Difference (5)
    This article is about a difference algorithm. It extracts changes from one version of an object to another. It helps storing a smaller amount of information. Template In a project, I have a template object with all the default settings for a widget. var template = { […]
  • August 19, 2011 jParser – Binary File Parsing revisited using Javascript (11)
    Writing a parser for a structured binary format such as a 3D model is extremely annoying. You have first to declare your file structure, and then go over every structure again and make a proper code to parse it. This is mainly caused because the lack of introspection of C/C++ and for […]
  • August 13, 2009 Dangerous Bracket Notation for Strings (18)
    The bracket notation for string is incomplete in Javascript and does not work in IE7. This is really painful to migrate to the .charAt(pos) equivalent, this is why i recommend you not to use it. // Bracket Notation "Hello World!"[6] // > "W" // Real Implementation "Hello […]