What’s new in GNU make 3.82

GNU make 3.82 hit the streets last week, the first new release of the workhouse build tool in over four years. Why so long between releases? To me the answer is obvious: the tool Just Works ™, so there’s no need to churn out new releases chasing the latest development fad. But as this release shows, there is still room to innovate, without compromising on the points that make the tool so great. The two improvements I find most interesting are .ONESHELL, and changes to pattern-search behavior:


Normally, gmake executes each line of a rule body or recipe using a separate invocation of the shell. With gmake 3.82, you can add the special target .ONESHELL to the makefile, which will tell gmake to run the entire recipe using a single shell invocation. For example, if your makefile contains the following:

all: @export FOO=1 @echo FOO is -$$FOO-

Without .ONESHELL, gmake will invoke the shell twice, as follows:

sh -c 'export FOO=1' sh -c 'echo FOO is -$FOO-'

Naturally, that will not produce the output you actually want (ie, “FOO is -1-“). With .ONESHELL, gmake instead invokes the shell just once:

sh -c 'export FOO=1 echo FOO is -$FOO-'

In addition to making it easier to write multi-line rule bodies, this feature makes it much more palatable to use alternative shells. For example, you could imagine using Perl as the shell:

SHELL=perl .SHELLFLAGS=-e .ONESHELL: all: @my $$foo = "1"; print "FOO is -$$foo-\n";

(Note the use of another 3.82 feature, .SHELLFLAGS, which allows us to control the command-line flags used with the shell; in this case I’ve set those to “-e”, the Perl flag for executing a script from the command-line).

Pattern search changes

Prior to version 3.82, when gmake finds multiple matches during a pattern search, it prefers patterns declared earlier in the makefile over patterns declared later. As of 3.82, gmake instead prefers the pattern that results in the shortest stem. That sounds a bit confusing thanks to the jargon, but I think this will actually cause gmake to better adhere to the principle of least astonishment. Here’s an example:

all: sub/foo.x %.x: @echo "Prefer first match (stem is $*)." sub/%.x: @echo "Prefer most specific match (stem is $*)."

Compare the output from gmake 3.81 and 3.82:

gmake 3.81
Prefer first match (stem is sub/foo).
gmake 3.82
Prefer most specific match (stem is foo).

gmake 3.82 prefers the second pattern because it is a more specific match than the first. Note that this is a significant backwards-incompatibility compared with previous versions of gmake!

Other changes

Besides those big changes, there are several smaller features, such as:

This special variable allows you to change the character used to mark the beginning of a command in a recipe from the default TAB character. I can only assume that the developers added this feature to quell the semi-regular complaints about make’s sensitivity to whitespace.
private variable modifier
Normally, gmake propagates target-specific variable assignments to the prereqs of the target. With the private modifier, you can restrict the scope of a target-specific variable assignment, so that it is not inherited by the prereqs.
undefine directive
The inverse of the familiar define directive, undefine lets you completely remove a variable definition.
define improvements
The define directive now supports the same assignment operators that regular variable assignment alows: :=, ?= and +=, for simple, conditional and appending assignments.

If you want to see the full list, you can find it in the NEWS file in the gmake source tree.

“Rumors of my death have been greatly exaggerated…”

Some naysayers claim make is outdated, but it’s clear that make is still alive and kicking (and if a new gmake release isn’t proof enough, take a look at some of the innovations we’ve put into Electric Make). A hearty congratulations to everybody who contributed, and especially to Paul Smith for driving the development and release effort. Keep up the good work!

Posted in News. Tags: , . 2 Comments »

2 Responses to “What’s new in GNU make 3.82”

  1. Top posts for September 2010 « blog.melski.net Says:

    […] What’s new in GNU make 3.82: 7% of page views […]

  2. Shell commands in GNU make « blog.melski.net Says:

    […] bene: if you are using gmake 3.82 or later, you can enable the .ONESHELL feature, which causes gmake to invoke the entire recipe using a single shell invocation, even if […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: