12
votes

I am learning makefiles and I know how to create a simple makefile. I am moving on to nested makefiles. Here is my directory structure

/src
...makefile
...main.cpp
...foo
......makefile
......foo.cpp
......foo.h

When root makefile is called, it calls the makefile in directory foo. Here are my questions

  1. Which makefile should I use to write code for linking all object files? If it is in the root makefile, do I need to specify all object file names there?
  2. Is this nested makefiles a best practice? Or is it good to have only one makefile which is at root?

Any help would be great!

3

3 Answers

18
votes

There is a lot to be said for not doing this. Read Recursive Make Considered Harmful. Also in PDF form.

The short short version is that recursive make effectively builds several disjoint but possibly overlapping dependency trees and can not guarantee either a correct or maximally efficient build. The problem get worse if you hope to build in parallel.

To solve the problem you arrange an single, non-recursive make that builds a single all-spanning dependency tree which allows make to solve all the above problems.

Example structures for non-recursive make and solutions to the several tricky problems that come up in writing them can be found in the original paper and in the answers to:

3
votes

Recursive make is generally considered harmful.

If you really want to be able to type "make" in the root dir and have it build everything using only POSIX makefiles, it is the only way. In that case, link the subprojects in their own directory, and final stuff together in root.

If you're willing to use gmake syntax, take a look at the Makefiles here: http://github.com/singpolyma/theveeb-ecosystem

2
votes

There are more modern build systems like SCons That have an easier syntax than make and avoid many pitfalls of make. For example SCons scans the source files to determine dependencies on it's own, whereas for make one needs to specify dependencies manually. If you e.g. add a new #include statement to an implementation file make will not recompile that implementation file if the header changes (unless you add the new dependency). SCons will automatically detect the new dependency and recompile whatever necessary.