Published on (
 See this if you're having trouble printing code examples

make: The Evolution and Alternatives

by Andy Oram, Robert Mecklenburg

Editor's note: The following article is adapted from the foreword to the third edition of Managing Projects with GNU make.

The make utility is an enticing servant, always there and always accommodating. Like the indispensable sidekicks found in many novels and movies, make starts out as the underappreciated supplicant to whom you throw a few odd jobs, and then gradually takes over the entire enterprise.

I had reached the terminal stage of putting make at the center of every project I touched when Steve Talbott, my supervisor and the author of the original O'Reilly classic Managing Projects with make, noticed my obsession and asked me to write the second edition. It proved to be a key growth experience for me (as well as a pretty wild ride) and my entry into the wonderful world of O'Reilly, but we didn't really think about how long the result would stay on the market. Thirteen years for one edition?

Enthralled in the memories of those days long ago when I was a professional technical writer, I'll indulge myself with a bulleted list to summarize the evolution of make since the second edition of Managing Projects with make hit the stands:

Related Reading

Managing Projects with GNU Make
By Robert Mecklenburg

As I watched these trends, it had been in the back of my mind for about a decade to write a new edition of Managing Projects with make. But I sensed that someone with a broader range of professional experience than mine was required. Finally, Robert Mecklenburg came along and wowed us all at O'Reilly with his expertise. I was happy to let him take over the book and to retire to the role of kibitzer, which earns me a mention on the copyright page of the book. (Incidentally, we put the book under the GNU Free Documentation License to mirror the GPL status of GNU make.)

Robert is too modest to tout his Ph.D., but the depth and precision of thinking he must have applied to that endeavor come through clearly in this book. Perhaps more important to the book is his focus on practicality. He's committed to making make work for you, and this commitment ranges from being alert about efficiency to being clever about making even typographical errors in makefiles self-documenting.

This is a great moment: the creation of a new edition of one of O'Reilly's earliest and most enduring books. Get yourself a copy and read about how an unassuming little tool at the background of almost every project embodies powers you never imagined. Don't settle for creaky and unsatisfying makefiles--expand your potential today.

Editor's note: The following is an adaptation of a portion of Managing Projects with GNU make, 3rd Edition written by author Robert Mecklenburg.

Alternatives to make

I've been programming in Java for about five years and I enjoy working in the language. There is, however, an annoying tendency in Java to reinvent the wheel. Of course, Java must have its own implementation of file access, socket communication, and database access. These are all done in the name of portability and seamless interaction with the rest of the language, and rightly so. But there are also Java implementations of the CVS protocol and LR(1) parser generators, and a Java version of make called Ant.

I recently finished writing the third edition of Managing Projects with GNU Make and made sure to include a chapter on Java. make is one of the major choices available for coordinating Java program compilations, along with various IDEs and Ant. Ant was created was because applying make to Java can be tricky. That's why Managing Projects with GNU Make contains a chapter on make and Java.

Let's see how Ant, IDEs, and make compare for managing the build process.


The Java community is very active, producing new tools and APIs at an impressive rate. One of these new tools is Ant, a build tool intended to replace make in the Java development process. Like make, Ant uses a description file to indicate the targets and prerequisites of a project. Unlike make, Ant is written in Java and Ant build files are written in XML.

To give you a feel for the XML build file, here is an excerpt from the Ant build file:

<target name="build"
        depends="prepare, check_for_optional_packages"
        description="--> compiles the source code">
  <mkdir dir="${build.dir}"/>
  <mkdir dir="${build.classes}"/>
  <mkdir dir="${build.lib}"/>

  <javac srcdir="${java.dir}"
         optimize="${optimize}" >
    <classpath refid="classpath"/>
  <copy todir="${build.classes}">
    <fileset dir="${java.dir}">
      <include name="**/*.properties"/>
      <include name="**/*.dtd"/>

As you can see, a target is introduced with an XML <target> tag. Each target has a name and dependency list specified with <name> and <depends> attributes, respectively. Actions are performed by Ant tasks. A task is written in Java and bound to an XML tag. For instance, the task of creating a directory is specified with the <mkdir> tag and triggers the execution of the Java method Mkdir.execute, which eventually calls File.mkdir. As far as possible, all tasks are implemented using the Java API.

An equivalent build file using make syntax would be:

# compiles the source code
build: $(all_javas) prepare check_for_optional_packages
        $(MKDIR) -p $(build.dir) $(build.classes) $(build.lib)
        $(JAVAC) -sourcepath $(java.dir) 			\
                 -d $(build.classes)     			\
                  $(debug)               			\
                  $(deprecation)         			\
                  -target $(			\
                  $(optimize)            			\
                  -classpath $(classpath)                       \
        $(FIND) . \( -name '*.properties' -o -name '*.dtd' \) | \
        $(TAR) -c -f - -T - | $(TAR) -C $(build.classes) -x -f -

This snippet of make uses techniques that this book hasn't discussed yet. Suffice to say that the prerequisite <filename>all.javas</filename> contains a list of all java files to be compiled. The Ant tasks <mkdir>, <javac>, and <copy> also perform dependency checking. That is, if the directory already exists, mkdir is not executed. Likewise, if the Java class files are newer than the source files, the source files are not compiled. Nevertheless, the make command script performs essentially the same functions. Ant includes a generic task, called <exec>, to run a local program.

Ant is a clever and fresh approach to build tools; however, it presents some issues worth considering:

Scripting languages, on the other hand, were invented and flourish precisely to address this type of issue. make has existed for nearly 30 years and can be used in the most complex situations without extending its implementation. Of course, there have been a handful of extensions in those 30 years. Many of them conceived and implemented in GNU make.

Ant is a marvelous tool. It has found wide acceptance in the Java community. However, before embarking on a new project, consider carefully whether Ant is appropriate for your development environment. This chapter will hopefully prove to you that make can powerfully meet your Java build needs.


Many Java developers use Integrated Development Environments (IDEs) that bundle an editor, compiler, debugger, and code browser in a single (typically) graphical environment. Examples include the open source Eclipse ( and Emacs JDEE (, and, from commercial vendors, Sun Java Studio ( and JBuilder ( These environments typically have the notion of a project build process that compiles the necessary files and enables the application execution.

If the IDEs support all of this, why should we consider using make? The most obvious reason is portability. If there is ever a need to build the project on another platform, the build may fail when ported to the new target. Although Java itself is portable across platforms, the support tools are often not. For instance, if the configuration files for your project include Unix- or Windows-style paths, these may generate errors when the build is run on the other operating system. A second reason to use make is to support unattended builds. Some IDEs support batch building and some do not. The quality of support for this feature also varies. Finally, the build support included is often limited. If you hope to implement customized release directory structures, integrate help files from external applications, support automated testing, and handle branching and parallel lines of development, you may find the integrated build support inadequate.

In my own experience, I have found the IDEs to be fine for small-scale or localized development, but production builds require the more comprehensive support that make can provide. I typically use an IDE to write and debug code, and write a makefile for production builds and releases. During development, I use the IDE to compile the project to a state suitable for debugging. But if I change many files or modify files that are input to code generators, then I run the makefile. The IDEs I've used do not have good support for external source code generation tools. Usually, the result of an IDE build is not suitable for release to internal or external customers. For that task I use make.


IDEs provide workable build environments for many small projects, but if your project grows beyond a couple of people or a single .jar file, you will probably want to consider more powerful build tools. At that point, you'll most likely choose between Ant and make. If you want to work with a scripting language and have a build that is transparent to your developers (i.e., tells you precisely what it is doing at each step), choose make. If you like XML or work in a development team unfamiliar with Unix software tools, consider using Ant.

I have many colleagues that have used both make and Ant. In truth, those that have spent more time with Windows and IDEs than Unix and bash prefer Ant. I'll stick with make, but you knew that.

Andy Oram is an editor for O'Reilly Media, specializing in Linux and free software books, and a member of Computer Professionals for Social Responsibility. His web site is

Robert Mecklenburg began using Unix as a student in 1977 and has been programming professionally for 23 years. He has worked in many fields ranging from mechanical CAD to bioinformatics, and he brings his extensive experience in C++, Java, and Lisp to bear on the problems of project management with make.

View catalog information for Managing Projects with GNU make, 3rd Edition

Return to

Copyright © 2009 O'Reilly Media, Inc.