How to quickly navigate an unfamiliar makefile

The other day, I was working with an unfamiliar build and I needed to get familiar with it in a hurry. In this case, I was dealing with a makefile generated by the Perl utility h2xs, but the trick I’ll show you here works any time you need to find your way around a new build system, whether it’s something you just downloaded or an internal project you just transferred to.

What I wanted to do was add a few object files to the link command. Here’s the build log, with the link command highlighted:

Should be easy, right? I just needed to find that command in the makefile and make my changes. Wrong. Read on to see how annotation helped solve this problem.

The thing is, the command I’m looking for doesn’t appear anywhere in the makefile. All of the rules look like this:

There’s not a single useful literal string in sight, so grep is right out. And it’s not like you could just start reading the makefile top-to-bottom to figure out which variables contribute to the command line that produces the output that you see in the log. The makefile is nearly a thousand lines long with literally hundreds of variable definitions:

It seems hopeless. This makefile suffers from a classic problem: unless you’re the guy who wrote it in the first place, it’s an impenetrable fog. You’re in for a world of hurt when you try to understand it, or worse, try to modify it. Lucky for me — and for you if you ever find yourself in this situation — there’s a powerful new tool in your toolbox: emake’s annotated build logs, or simply annotation.

If you have ElectricAccelerator or SparkBuild, a free gmake- and NMAKE-compatible make replacement, you just need to enable annotation on your next build:

Now you can search build.xml for the log output or the command-line that you’re interested in. You can use ElectricInsight or SparkBuild Insight, of course, but for a simple query like this I just use less. Searching for the log output of the command I’m looking for (gcc -shared) leads me to this:

Now, I just scan back a few lines to find the start of the <job> tag containing that text. The file attribute tells me which makefile contains the rule definition, and the line attribute tells me which line it starts on:

Bingo! The rule I want starts on line 469 of the file Makefile. Using that as an anchor it’s now trivial to see how to modify the makefile to produce the result I’m after.

The best tool for the job

Trying to figure out how a build system is put together can feel like being dropped in the middle of a dense jungle. Annotated build logs are like a map leading you back to daylight. There’s nothing else like them.

Build Acceleration and Continuous Delivery

Continuous Delivery isn’t continuous if builds and tests take too long to complete. Learn more on how ElectricAccelerator speeds up builds and tests by up to 20X, improving software time to market, infrastructure utilization and developer productivity.

Follow me

Eric Melski

Eric Melski was part of the team that founded Electric Cloud and is now Chief Architect. Before Electric Cloud, he was a Software Engineer at Scriptics, Inc. and Interwoven. He holds a BS in Computer Science from the University of Wisconsin. Eric also writes about software development at
Follow me

Share this:

4 responses to “How to quickly navigate an unfamiliar makefile”

  1. Jean says:

    Just nitpicking: h2xs does not generate makefiles, it generates Perl code ( Makefiles are actually generated by Perl module called ExtUtils::MakeMaker. The complexity is caused by Perl having three different places to install code, called core, vendor and site, besides doing an installation mock-up for tests.

    • Eric Melski says:

      Thanks for the correction. Actually, I think it further underscores my point — I’m not a domain expert in the build system produced by this system (h2xs plus MakeMaker), and yet I was able to figure out how to work with it very quickly thanks to the assist from emake.

  2. Anthony Wong says:

    What about using some of the make debug tips you’ve mentioned in the past for obtaining variable values:

    @echo ‘====================’
    @echo ‘NAME: $*’
    @echo ‘——————–‘
    @echo ‘VALUE: $($*)’
    @echo ‘——————–‘
    @echo ‘RULE: $(value $*)’
    @echo ‘——————–‘
    @echo ‘ORIGIN: $(origin $*)’
    @echo ‘====================’

  3. Simon Wright says:

    What about line 5 of the Makefile, “Don’t edit this file, edit Makefile.PL instead.”?

    And something has happened to the code sections; I see the raw HTML, not the highlighted effect you probably intended (Safari, Mac OS X Mavericks)

Leave a Reply

Your email address will not be published. Required fields are marked *


Subscribe via RSS
Click here to subscribe to the Electric Cloud Blog via RSS

Subscribe to Blog via Email
Enter your email address to subscribe to this blog and receive notifications of new posts by email.