Gnu Make

Make [] is a tool invented by StuFeldman which controls the generation of executables and other non-source files of a program from the program's source files. It first appeared in Version 7 Unix from BellLabs in 1979.

Make gets its knowledge of how to build your program from a file called the makefile, which lists each of the non-source files and how to compute it from other files. When you write a program, you should write a makefile for it, so that it is possible to use Make to build and install the program.

So GnuMake is an example of a MakeTool.
More generally, make uses rules to determine how to achieve goals (over a limited domain). Make is the most successful and widely used ArtificialIntelligence program around. It is in essence a LogicProgramming language, although for unknown reasons nearly all of the additional features added to versions of Make since 1979 have ignored this.

I love it, I hate it. It now automatically manages all my dependencies for me thanks to RecursiveMakeConsideredHarmful, but it can only manage to do this for .c files because patsubst and pattern rules use the same wildcard syntax and there is no way to use the outer wildcard in the inner context. It also has to rebuild all the dependency files in order to clean up the working directory (make clean). It is the best Make I have ever used, and I still hate it. -- AlastairBridgewater
I have found make to be the most powerful tool in my arsenal. That, and cron are my allies. Make isn't just for programs, it is for data flow, UnitTests, web pages, database queries, and more. I find that the script that make writes for me is ALWAYS (Shout for joy) better than one I could write myself. I really appreciated the reference to RecursiveMakeConsideredHarmful and have begun looking into how to consolidate a small handful of thousand line Makefiles (Which are easy to RefactorMercilessly) into one with symbolic links to it. -- ChrisGarrod
Q: If God had not given us Makefiles, it would have been necessary to invent them.

A: I guess that is what DNA is.
I have a small Makefile for my Objective Caml programs, and another one for my C++ programs. I copy them around wherever I go; I only have to edit the list of source files, the rest happens automatically. Once you have the initial Makefile which does what you want, using make is really a joy; however, writing that first Makefile can be a bit painful if you have no prior experience with make. One tip: make sure you put a tab in the right place, rather than spaces! -- StephanHouben
To stop GnuMake building dependencies when you 'make clean', check for 'clean' in $(MAKECMDGOALS). Only fairly recent versions have $(MAKECMDGOALS) though.
Most modifications to StuFeldman's program try to provide a way to include information from other places in makefiles. The include syntax is highly variable. Hmmm, I seem to be talking about a variety of make programs, not just GnuMake. Maybe I too can figure out how to RefactorMercilessly on WardsWiki. -- Chris Garrod
Make is so useful, the only question one could have about it is why has no one invented a replacement which uses a syntax humans can grok?

but make syntax is very simple. I don't understand this comment. If we were talking about hand-rolling files (like the bad old days), I would agree! If you find make inscrutable then perhaps you would enjoy PerforceJam I have recently tried it on a few cross-platform projects, with pretty good results. I am not sure how well it scales to really large projects - I know I can do that with make, but I also know it will be a real pita.
I've found myself trying to write a real build system for over 25,000 source files. Currently, my company uses Maven, and it's a POS. Builds take over 3 hours without maven tests, 6-7 with, and the build is far from incremental, and it is almost entirely single threaded due to Maven. (Not to be a bash Maven post, but to give perspective.) Trying to work on it is abysmal. Either you take hours to build from root, or you pick and choose what to build, hoping you don't miss a dependency.

I'd like to know if there's a build system out there which

1- is perfectly incremental or supports easily making the build be perfectly incremental (A naive GNU Make system would not trigger a rebuild when a source file is removed; no prereqs are newer than targets, so no rebuild, even though you almost certainly want to rebuild that dll when a cpp file no longer goes into it.),

2- parallelizes a build (and possibly distributed builds as GNU Make can be "hacked" to do in various ways),

3- is Java / C++ / code generation / Lisp / etc. agnostic like GNU Make (My company uses a dozen custom build tools which is painful in Maven, and Maven doesn't like C++ code all that much either.),

4- is very very fast, (With my GNU Make system, have it parsing all of the makefiles and stating all the files for a 25,000 source file build in under 25 seconds [No recursive make].)

5- and only then easy to work with?

I've almost gotten there with GNU Make 3.81, but it was somewhat painful and tedious to do. I've abstracted away all the really hard stuff so that users of the build system use a simple declarative structure, like define your source folder, your output folder, and your dll name, then say "include", and voila, make and my build system written in makefiles handles the rest.

Also, what would be an appropriate venue, do you think, to post what I've done thus far looking for comments?

EditText of this page (last edited June 23, 2009) or FindPage with title or text search