This review was originally printed in the UKUUG newsletter, which is now defunct.
Authors: John Graham-Cumming
Publisher: No Starch Press
IBSN: 9781593276492
Pages: 236
Published: 2015
GNU Make is an important piece of infrastructure in the open source ecosystem, but do you fully understand its capabilities? The online documentation makes for a good starting point, but this book promises to take you to the next level.
The first chapter is a quick refresh of some concepts, such as the different types of variables available in Make, built-in functions and the differences between recent versions of make. There are no reasons to use a build system, discussions of Make versus other software etc. that you would get from an introductory text, and the author makes it clear up front that this chapter is not a substitute for reading the documentation provided with the software.
Chapter two covers debugging, including a useful section on how to implement tracing if you are using a version below 4.0. Some of the examples seem like highly convoluted hacks, but this is largely due to some of the quirks of Make rather than any fault of the author.
The third chapter is dedicated to building and, perhaps more important in Make, rebuilding. Lots of useful corner cases and scenarios are covered beyond the standard ‘have any dependencies changed?’ rule. Particularly useful examples cover rebuilding when environment variables have changed (e.g. CPPFLAGS), when the contents of a file have changed (which does not always result in a timestamp update) and automatically generating dependency rules for related resources such as C header files.
Chapter four takes us through a variety of problems and pitfalls faced by maintainers as projects increase in size and complexity. One thing I learnt from this is that Make’s ifndef statement does not actually mean ‘if not defined’ but ‘if not defined or defined and empty’ – a distinction I would not otherwise been aware of. The fact that this chapter is by far the longest in the book gives you an indication of just how confusing Make can be, even for the intermediate or expert user.
The next chapter demonstrates ways to ‘push the envelope’ with Make by extending its language through the creation of new functions. Whilst interesting, I did struggle to think of situations where, for example, the ability to perform division in a Makefile would actually be useful, but should you wish to do so the author has described the solution in detail.
The book concludes with a chapter describing the author’s GNU Make Standard Library, a collection of useful extensions to Make started by the author. A lot of effort has clearly gone into creating and documenting this library and it will save you reinventing the wheel on every large project.
If you need to go beyond the online documentation for Make, you should buy this book – it is one of the best I have reviewed.