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 a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.