16

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!

singpolyma
  • 10,999
  • 5
  • 47
  • 71
Navaneeth K N
  • 15,295
  • 38
  • 126
  • 184

3 Answers3

21

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:

Community
  • 1
  • 1
dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
3

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

singpolyma
  • 10,999
  • 5
  • 47
  • 71
  • 1
    You can use a POSIX (non-GNU) make to perform a non-recursive build by breaking it into two steps: 1) concatenate all make.inc files in all subdirs; 2) run the resulting makefile. But most people use GNU make anyway, which has the "include" directive. – j_random_hacker Apr 07 '09 at 03:54
  • Ah, that's true, I never though of the concatenation hack. I tend to use include. Normally I want to be very POSIX, but with makefiles sometimes that's a bit hairy because of the no include directive :) – singpolyma Apr 07 '09 at 03:57
2

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.

lothar
  • 19,853
  • 5
  • 45
  • 59