GNU Make user-defined functions

[article]

this:

map = $(foreach a,$2,$(call $1,$a))

The first argument is the function to call, the second is the list to iterate over.   Here's an example use of map: we use it to iterate over a list of variable names and print out the defined value and the expanded value of each variable.

print_variable = $1 ($(value $1) -> $($1))

print_variables = $(call map,print_variable,$1)

VAR1 = foo

VAR2 = $(VAR1)

VAR3 = $(VAR2) $(VAR1)

$(info $(call print_variables,VAR1 VAR2 VAR3))

print_variable takes the name of a variable as its first and only argument and returns
a string consisting of the name of the variable, its definition and its value.   print_variables applies print_variable to a list of variables using map.

Here's the output of the above Makefile snippet:

VAR1 (foo -> foo) VAR2 ($(VAR1) -> foo) VAR3 ($(VAR2) $(VAR1) -> foo foo)

GNU Make functions can also be recursive and so it's possible to $(call) yourself.   Here's an implementation of the common reduce function using recursion.

reduce = $(if $(strip $2),$(call reduce,$1,$(wordlist 2,$(words $2),$2),$(call $1,$(firstword $2),$3)),$3)

reduce takes two arguments: a function that will be called by reduce and a list to process.  The first argument is called with two arguments: each element of the list in reduce's second argument and the result of the previous call to the function.

To see this in action we can create a list unique function that removes duplicates without reordering:

check_uniq = $(if $(filter $1,$2),$2,$2 $1)

uniq = $(call reduce,check_uniq,$1)

$(info $(call uniq,c b a a c c b a c b a))

This works because reduce will call check_uniq with each member of the input list in turn building up a new list from the result of check_uniq.  check_uniq just determines whether the element is present or not (using $(filter)) and returns the list with the element appended if it was not already seen.

Conclusion

GNU Make user-defined functions can do a lot.  If you want to see the extreme use of them examine how the GNU Make Standard Library pushed GNU Make user-defined functions to their limits.

About the author

John Graham-Cumming's picture John Graham-Cumming

John Graham-Cumming is Co-Founder at Electric Cloud, Inc . Prior to joining Electric Cloud, John was a Venture Consultant with Accel Partners, VP of Internet Technology at Interwoven, Inc. (IWOV), VP of Engineering at Scriptics Corporation (acquired by Interwoven), and Chief Architect at Optimal Networks, Inc. John holds BA and MA degrees in Mathematics and Computation and a Doctorate in Computer Security from Oxford University. John is the creator of the highly acclaimed open source POPFile project. He also holds two patents in network analysis and has others pending.

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!

Upcoming Events

Sep 22
Sep 24
Oct 12
Nov 09