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:

.ONESHELL

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
gmake 3.82

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:

.RECIPEPREFIX
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!

 


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.

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 http://blog.melski.net/.

Share this:

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

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

  2. [...] 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 [...]

  3. Keith says:

    This is so cool! I was just disappointed last week that GNU Make didn’t have an undefine.

Leave a Reply

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.

Upcoming Webinars:


ElectricFlow Deploy: Application Release Automation at Enterprise-Scale
Oct 7, 10AM PST
Register Now »


banner_continuous-integration-at-scale
banner_huddle_free-build-acceleration