GNU Make user-defined functions, part 2

[article]

built-in functions are defined in the file function.c .  The first place to look is the table of functions

that GNU Make knows about.  It's called function_table_init[] and can be found on line
2,046:

static struct function_table_entry function_table_init[]
=

{

~ /* Name/size */                    /* MIN MAX EXP? Function */


{ STRING_SIZE_TUPLE("abspath"),       0,  1,  1,  func_abspath},

~  {
STRING_SIZE_TUPLE("addprefix"),     2,  2, 
1,

func_addsuffix_addprefix},

~  { STRING_SIZE_TUPLE("addsuffix"),     2, 
2,  1,

func_addsuffix_addprefix},

~  { STRING_SIZE_TUPLE("basename"),     
0,  1,  1,  func_basename_dir},

~  { STRING_SIZE_TUPLE("dir"),           0, 
1,  1,  func_basename_dir},

~  { STRING_SIZE_TUPLE("notdir"),        0,  1, 
1,  func_notdir_suffix},

~  { STRING_SIZE_TUPLE("subst"),         3,  3,  1, 
func_subst},

~  { STRING_SIZE_TUPLE("suffix"),        0,  1,  1, 
func_notdir_suffix},

~  { STRING_SIZE_TUPLE("filter"),        2,  2,  1, 
func_filter_filterout},

~  { STRING_SIZE_TUPLE("filter-out"),    2,  2,  1, 
func_filter_filterout},

~  { STRING_SIZE_TUPLE("findstring"),    2,  2,  1, 
func_findstring},

~  { STRING_SIZE_TUPLE("firstword"),     0,  1,  1, 
func_firstword},

~  { STRING_SIZE_TUPLE("flavor"),        0,  1,  1, 
func_flavor},

~  { STRING_SIZE_TUPLE("join"),          2,  2,  1, 
func_join},

~  { STRING_SIZE_TUPLE("lastword"),      0,  1,  1, 
func_lastword},

~  { STRING_SIZE_TUPLE("patsubst"),      3,  3,  1, 
func_patsubst},

~  { STRING_SIZE_TUPLE("realpath"),      0,  1,  1, 
func_realpath},

~  { STRING_SIZE_TUPLE("shell"),         0,  1,  1, 
func_shell},

~  { STRING_SIZE_TUPLE("sort"),          0,  1,  1, 
func_sort},

~  { STRING_SIZE_TUPLE("strip"),         0,  1,  1, 
func_strip},

~  { STRING_SIZE_TUPLE("wildcard"),      0,  1,  1, 
func_wildcard},

~  { STRING_SIZE_TUPLE("word"),          2,  2,  1, 
func_word},

~  { STRING_SIZE_TUPLE("wordlist"),      3,  3,  1, 
func_wordlist},

~  { STRING_SIZE_TUPLE("words"),         0,  1,  1, 
func_words},

~  { STRING_SIZE_TUPLE("origin"),        0,  1,  1, 
func_origin},

~  { STRING_SIZE_TUPLE("foreach"),       3,  3,  0, 
func_foreach},

~  { STRING_SIZE_TUPLE("call"),          1,  0,  1, 
func_call},

~  { STRING_SIZE_TUPLE("info"),          0,  1,  1, 
func_error},

~  { STRING_SIZE_TUPLE("error"),         0,  1,  1, 
func_error},

~  { STRING_SIZE_TUPLE("warning"),       0,  1,  1, 
func_error},

~  { STRING_SIZE_TUPLE("if"),            2,  3,  0, 
func_if},

~  { STRING_SIZE_TUPLE("or"),            1,  0,  0, 
func_or},

~  { STRING_SIZE_TUPLE("and"),           1,  0,  0, 
func_and},

~  { STRING_SIZE_TUPLE("value"),         0,  1,  1, 
func_value},

~  { STRING_SIZE_TUPLE("eval"),          0,  1,  1, 
func_eval},

#ifdef EXPERIMENTAL

~  { STRING_SIZE_TUPLE("eq"),           
2,  2,  1,  func_eq},

~  { STRING_SIZE_TUPLE("not"),           0,  1,  1, 
func_not},

#endif

};

Each line defines a single function, and consists of 5 pieces of information: the name of the function, the minimum number of arguments  that the function must have, the maximum number of arguments (specifying a maximum of zero with a non-zero minimum means that function can have  unlimited number of arguments), whether the arguments should be expanded, and the name of the C function that actually performs the function.

For example, here's the definition of the findstring function:

~  {
STRING_SIZE_TUPLE("findstring"),    2,  2,  1,  func_findstring},

So
that function is called findstring, it has a minimum of 2

arguments,
a maximum of 2 and the arguments should be expanded before

calling the C
function func_findstring.

func_findstring (which is in function.c at line 819) does the work:

static
char*

func_findstring (char *o, char **argv, const char *funcname
UNUSED)

{

~  /* Find the first occurrence of the first string in the
second.  */

~  if (strstr (argv[1], argv[0]) != 0)

~    o =
variable_buffer_output (o, argv[0], strlen (argv[0]));

~  return
o;

}

The C functions that implement GNU Make built in functions have three arguments: [tt] o[/tt] (a pointer to a buffer into which output of the function should be written), argv (the arguments of the function as a null-terminated array of strings) and funcname   (which is a string containing the name of the function; most functions don't need this but it can be helpful if one C routine handles more than one GNU Make function).

You can see that [t t]func_findstring[/tt] just used the standard library strstrfunction to find the presence of its second argument (in argv[1]) in its first (in argv[0]).
func_findstring makes use of a very handy GNU Make C function called variable_buffer_output (which is defined in expand.c at line 57). variable_buffer_output
is used to copy a

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