Recursive Make Considered Harmful

See http://www.canb.auug.org.au/~millerp/rmch/recu-make-cons-harm.html -- I found it good food for thought. Link has rotted. https://web.archive.org/web/20070205051133/http://members.canb.auug.org.au/~millerp/rmch/recu-make-cons-harm.html

-- BillTrost

But see http://www.dataclub.fi/oreilly/imake.html for another alternative. Since ImakeTool creates Makefile's by a macro expansion process, it is much easier to embed accurate dependency calculations and other Makefile optimizations rarely done by hand within it. And it is a lifesaver if you must build for multiple platforms from one source set.

The biggest obstacle to one big Makefile may be political: it creates one file where misediting can block everyone from working.

-- MarkSwanson

One can use "include" to include project makefiles inside one large "metamakefile".

Many OpenSource projects use GNU AutoConf instead of ImakeTool, there is a tutorial at http://www.amath.washington.edu/~lf/tutorials/autoconf/

-- MarcusDenker

I've tried the above and several more now defunct, but the best IMHO is OSE MakeIt, which does everything I've ever wanted to do in a build tool and a lot more. Best of all it's written entirely in GnuMake, so when you need to extend it you don't have to struggle with someone's braindead scripting language. And it's free. An InsanelyGreat tool. --PeterMerel

Try out Premake (http://premake.sourceforge.net/). remake takes a script file in Lua with a source list, build settings, include flags etc, and can create both GNU Makefiles and Visual Studio projects/workspaces/solutions. Very good if platform independence is important for you since you can easily make the Lua script set different options depending on the target OS. -- SimonBrenner
Imake? That only exacerbates the problem. You still have the agony of invoking make recursively, only now you get to do it several times. And you still have the problem that someone can trash something by misediting a single file (one of the imake library files, for instance) -- only now, it is more likely someone will trash something because so few people really understand how imake works, and fixing it is harder because of the maze of includes that one has to look through to find a bad definition. Rumor has it that imake's author disclaims any memory of having written it.

Autoconf misses the point, too -- generating the Makefiles and then invoking them recursively is painful on several fronts. It doesn't matter where the makefiles come from.

-- BillTrost


I came here to disagree, but I end up having to respond, YES!!!!. That page solves a problem I've been having that I couldn't figure out how to handle. Thank you, Bill. Um, Peter, is there any documentation for that online which is not a few score links with little to say at each? (Ok, I'm sick. I read the zshall manpage. I realize this isn't healthy. But it solves the whole navigation problem, and it lets me keep away from rodents for longer.) -- EdGrimm

Yes, there is a postscript version. I've just added a link to it to the MakeIt page.

Whatever happened to simple text files? Oh well, time to stress out old pstoascii again.. (unless you kill trees, postscript doesn't allow people respite from rodents...)
Actually I have to disagree. What that document describes is how recursive MAKE is harmful if done improperly. I'm using a recursive makefile in my current project, which would be significantly more unwieldy if it were all merged into one. Besides which, with the way my code editor is set up it is trivial to either do a complete build or just build one component, depending on how much I've changed between builds. (I should probably add that I've never needed to do a clean build or to build more stuff than was actually changed, unless I've changed the global compiler settings or something similar and so actually want to). -- GavinLambert
The specific mode of failure given in the "harmful" article is that the bee and ant both rely on parse.h which itself is dependent on parse.y. The problem lies in that only one directory of makefile has the knowledge for the dependency of parse.h <-- parse.y and how to build parse.h if it is out of date.

This problem is encountered often in practice: 1. .h files dependent on IDL (interface descriptor language) file dependencies. 2. My own most recent situation involves javah generating .h files from .class files, which are dependent on .java files:
        file.c <-- file.h <-- jfile.class <-- jfile.java

This will be a problem everywhere code is generated by a computer rather than written by a human. Because this scenario is the exception and not the most common practice, it makes more sense to me that both subdirectory Makefiles know how to build parse.h and parse.c from parse.y. The author would then argue that I've merely pulled down the top level Makefile into a subdirectory. Yes, in this instance that is true, but in general dealing with computer generated source files is a very small minority of instances that the duplicated rule would be a small fraction of the rules to be addressed.

In my #2 example above, it means that the subdirectory containing mostly C code rules also has rules & dependencies about how to build jfile.class. This works out very well for us as it maintains consistent rules and allows developers to stay out of each other’s way - which is the original intent of the subdirectory based recursive Makefile.

-- Nat Ersoz

However, you violate the DontRepeatYourself principle; where I work, we use a very similar method for dealing with recursive Ant builds, and it's bitten us horribly as developer-group A touches his own Ant scripts in a manner incompatible with developer-group B's methods. The result is a top-level Ant script that must include unique knowledge of how to build the sub-projects, which utterly defeats the purpose of breaking things up in the first place.

A non-recursive make system is the only, let me repeat this: the only, solution to the problem, because it is the only way a project's global dependency tree can be assessed by the tool. Frankly, we should all be using languages with proper module support built-in anyway, but in the absence of this, a properly engineered Makefile, even if generated by a higher-level tool, can serve as a useful substitute. The less the recursion, the faster the build, the faster errors are reported when things break, the more precise the errors, and easier to maintain overall. I've worked extensively with recursive (usually Autotools) make files, and I can honestly say, unequivocally, that it is the biggest waste of my time ever.

-- Samuel A. Falvo II

Aegis http://aegis.sourceforge.net/ has its own Make replacement, "cook". Cook makes stuff from a recipe... It's actually very good for interpreted languages and excellent for C and C++.

-- JakobEriksson

Amusing screen shot: -- ChrisGarrod
CategoryConsideredHarmful

EditText of this page (last edited November 13, 2014) or FindPage with title or text search