link: "Recursive Make Considered Harmful"
christopher at nu.org
Mon Jan 10 18:42:33 PST 2005
On Tue, Jan 11, 2005 at 11:14:36AM +1000, Andrew Hacking wrote:
I read Peter Miller's paper a while back when designing a build system
and perhaps the most difficult part is the handling of multiple targets
and per target variables/flags. If you need different
compiler/linker/tool flags (CFLAGS/LDFLAGS/etc) for different
components, the scheme presented in the paper falls apart. You will
notice that the example given in the paper is extremely simple and can
only build a single program, albeit from fragments in different
directories. There is no treatment on how it would be possible to build
multiple libraries and programs with differing build flags, include
paths, (what if filenames are not globally unique ?) and differing
object and library linkage requirements.
Peter does eat his own dogfood, though: the Makefile for his aegis SCM
system includes separate invocations of the compiler for each object
file as well as the expected separate invocations of the linker for
each library and program. This Makefile is generated by a program.
scons is a DMT worth looking at: it uses a hierarchy (if you want) of
files describing what needs to be done for making things, so you can
have different flags, include directories, etc., where you need them,
but the actual construction is done only at the top level,
I found when moving a (userspace and kernel) multi-OS project from a
recursive (GNU) makefile scheme to scons that the line count dropped
by 90% and the file count by even more. I think it also built
quicker, but didn't collect numbers to prove it.
It was at this point I walked away, ironically perhaps, with the opinion
of the approach presented "considered harmful". However I have since
read of a somewhat workable system here:
... but it requires GNU make and the makefile fragments end up having
too much cryptic/convoluted logic for my liking. I prefer declarative
easy to read makefiles with all of the fancy "how-to" logic hidden away
in one or more included "build-logic" makefiles.
The link above still doesn't handle separate build/object trees (for
those who like to keep their source tree pristine), and may have some
other gotchas that are not immediately evident.
My conclusion from having constructed recursive build systems (from
scratch, so it's my own fault...) and then making them non-recursive,
is that the main problem with recursive make is the way make is used:
people keep trying to do non-declarative things, like autogenerating
rules, multiple make invocations with different arguments, doing
clever stuff conditional on run time things, etc.
If we could only stick to the declarative subset of make, it would be
much easier to collect a whole bunch of things from a directory
hierarchy and process it nicely.
If non-declarative stuff is necessary, it would be really nice to make
all those decisions up front, and then invoke make (with the
configuration just determined) to do the boring stuff. Maybe then we
could all win.
More information about the Kernel