Makefile Optimization: $(eval) and macro caching

[article]

$(FOO) to $(call cache, FOO) with a simple find and replace:

C := 1234567890 ABCDEFGHIJKLMNOPQRSTUVWXYZ

C += $C

C += $C

C += $C

C += $C

C += $C

C += $C

C += $C

C += $C

C += $C

C += $C

C += $C

FOO
= $(subst 9,NINE,$C)$(subst 8,EIGHT,$C)$(subst 7,SEVEN,$C)$(subst
6,SIX,$C)$(subst 5,FIVE,$C)$(subst 4,THREE,$C)$(subst 2,TWO,$C)$(subst
1,ONE,$C)

_DUMMY := $(call cache,FOO)

... repeated 200 times ...

.PHONY: all

all:

Running this on my machine shows that there's now one access of FOO, the same 9 accesses of C and a run time of 2.4s.   It's not as fast as the := version (which took 1.8s), but it's still 24% faster.  On a big Makefile this simple technique could make a real difference.

Wrapping Up

The fastest way to handle macros is to use := whenever you can, but it requires a care and attention and is probably best only done in a new Makefile (just imagine trying to go back and reengineer an existing Makefile with :=).   

If you're stuck with = then the little cache function I've presented here can give you a speed boost that'll be especially appreciated by developers doing incremental short builds.

And I hope I've whetted your appetite for the $(eval) function.  It's a very powerful tool.

About the author

AgileConnection is one of the growing communities of the TechWell network.

Featuring fresh, insightful stories, TechWell.com is the place to go for what is happening in software development and delivery.  Join the conversation now!