Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MAKEPP_FUNCTIONS(1)		    Makepp		   MAKEPP_FUNCTIONS(1)

NAME
       makepp_functions	-- Functions in	makepp

DESCRIPTION
       A: absolute_filename,
	 absolute_filename_nolink,
	 abspath,
	 addprefix,
	 addsuffix,
	 and,  B: basename,  C:	call,  D: dir,
	 dir_noslash,  E: error,  F: filesubst,
	 filter,
	 filter_out,
	 filter_out_dirs,
	 findfile,
	 find_first_upwards,
	 find_program,
	 findstring,
	 find_upwards,
	 first_available,
	 firstword,
	 foreach,  I: if,
	 iftrue,
	 infer_linker,
	 infer_objects,
	 info,	J: join,  M: make,
	 makemap,
	 makeperl,
	 map,
	 "mktemp",  N: notdir,	O: only_generated,
	 only_nontargets,
	 only_phony_targets,
	 only_stale,
	 only_targets,
	 or,
	 origin,  P: patsubst,
	 perl,
	 phony,
	 prebuild,
	 print,	 R: realpath,
	 relative_filename,
	 relative_to,  S: shell,
	 sort,
	 strip,
	 subst,
	 suffix,  T: temporary,	 W: warning,
	 wildcard,
	 word,
	 wordlist,
	 words,	 X: xargs

       Any expression of the format "$(name)", where "name" is not the name of
       a variable, or "$(name arg1 arg2	arg3)" is interpreted as a function
       call.  The name may contain letters, underscores, or hyphens; to	avoid
       confusion, you may use hyphens or underscores interchangeably, since
       internally hyphens are converted	to underscores.	 Evaluating such an
       expression simply invokes a Perl	subroutine.  If	"name" is preceded by
       "&" it runs the builtin command or script of that name within the
       makepp process, and returns the standard	output.	 If the	name does not
       name a function it is transformed to an invocation of call.

       As with variables you have a choice of "$(name ...)" or "${name ...}".
       Where the arguments contain these signs,	either use the other, or
       double it as in "$((name	...() ))".  Doubling is	also useful if you
       need the	arguments to span several lines.  The newlines are then
       treated as spaces, except maybe in "define".  There is also the syntax
       "$[name ...]" or	$[[name	...]], which gets evaluated while reading the
       makefile, before	grokking rules and other constructs.

       Makepp has a number of builtin functions	which may be useful.  It
       supports	almost all of GNU make's textual functions (see	GNU make's
       documentation for details), and some of its own.	 You can define	Perl
       subroutines to do whatever you like.  See the "sub" statement and the
       section on extending makepp for more details.

   Conditional Functions
       and condition1[,condition2[,condition3...]]
	   The	and function provides a	Xshort-circuitingX AND operation. Each
	   argument is expanded, in order. If an argument expands to an	 empty
	   string  the processing stops	and the	result of the expansion	is the
	   empty string. If all	arguments expand to a  non-empty  string  then
	   the result of the expansion is the expansion	of the last argument.

       if string, result-if-string-not-blank[, result-if-string-blank]
       iftrue string, result-if-string-true[, result-if-string-false]
	   An  alternative  to the "ifeq", etc., statements.  If the string is
	   not blank (i.e., the	condition is true), the	second	argument  (the
	   "then"  clause)  is	returned  (after  variable  expansion);	if the
	   string  is  blank,  the  third  argument  (the  "else"  clause)  is
	   returned.

	   For example,

	       CFLAGS := $(if $(filter gcc egcc, $(CC)), -g -Wall, -g)

	   defines  CFLAGS to be "-g -Wall" if the variable CC is either "gcc"
	   or "egcc", and "-g" otherwise.  (This is  what  the	default	 build
	   rules do.)

	   "iftrue" is similar to "if",	except that the	string 0 is treated as
	   blank.

       or condition1[,condition2[,condition3...]]
	   The	or  function  provides a Xshort-circuitingX OR operation. Each
	   argument is expanded, in order. If an argument expands  to  a  non-
	   empty  string  the processing stops and the result of the expansion
	   is that string. If, after all arguments are expanded, all  of  them
	   are	false  (empty),	 then the result of the	expansion is the empty
	   string.

   File	and Filename Functions
       absolute_filename files
       abspath files
	   Converts relative filenames into absolutes without .	 or  ...   For
	   example,	  "$(absolute_filename xyz.c)"	     might	return
	   "/usr/src/our_project/subdir/xyz.c".

       absolute_filename_nolink	files
       realpath	files
	   Like	 absolute_filename,  but  ensures  that	 symbolic  links   are
	   resolved.

       basename	filenames
	   The	basename  is  the entire file name (with the directory), minus
	   the	text   after   and   including	 the   last   period.	 E.g.,
	   "$(basename myfile/version-1.0-module.c)"			    is
	   "myfile/version-1.0-module"

       dir filenames
	   Extracts the	directory part of each	file  in  the  filename	 list,
	   including  the  trailing  slash.   Returns  "./"  if	 there	is  no
	   directory in	the filename.

       dir_noslash filename
	   Same	as "$(dir )" except that it doesn't return the trailing	slash.

       filesubst pattern, substitute, words
	   Perform a pattern substitution on  file  names.	 This  differs
	   from	 patsubst  in  that  it	 will perform correctly	when alternate
	   names for directories are  given  (as  long	as  they  precede  the
	   percent sign).  For example,

	       $(filesubst ./src/%.c, %.o, $(wildcard src/*.c))

	   will	work with filesubst but	not with patsubst.

       filter_out_dirs filenames
	   Returns all filenames that do not refer to directories.

       findfile	filename, path
	   Finds  a file in the	specified path,	or in the environment variable
	   PATH	if nothing is specified.   This	 can  be  useful  for  finding
	   binaries or include files.  For example,

	       TCL_INCLUDE := -I$(dir_noslash $(findfile tcl.h,	\
		   /usr/local/stow/tcl-8.4.5-nothread/include \
		   /usr/include/tcl8.4 /usr/include/tcl	\
		   /net/na1/tcl8.4a3/include /net/na1/tcl8.4a3/include))

	   This	 locates  the  file  tcl.h  by	searching  all	of  the	 above
	   directories.	 The absolute path to  the  file  is  returned.	  Then
	   "$(dir_noslash )"  extracts	that directory,	and it is put into the
	   include path.

       find_program name
	   Return the first program in the list	that can be found in the PATH.
	   This	is useful when there are multiple equivalent programs that may
	   be used, and	you just want to pick one of them.  For	example,  here
	   is  the  default definition of several common variables that	makepp
	   supplies if you do not put one in your makefile:

	       CC = $(find_program gcc egcc pgcc c89 cc) # and more, depending on machine
	       F77 = $(find_program f77	g77 fort77)
	       CXX = $(find_program g++	c++ pg++ cxx CC	aCC)

	   If none of the programs is found,  "$(find_program )"  returns  the
	   string  not-found, and logs what was	not found.  This usually won't
	   result in a functional makefile, but	 it  will  tend	 to  make  for
	   better error	messages.  For example,	if you do something like this:

	       %.o : %.c
		   $(CC) $(inputs) -o $(outputs)

	   and	makepp	can't  find  a	C  compiler in the list	above, it will
	   substitute not-found.  Otherwise the	shell would attempt to execute
	   the source file and the resulting error  message  might  be	really
	   strange.

       find_upwards filename
	   Searches  for  a  file  of  the  given name in the directory	., ..,
	   ../.., ../../..,  etc.,  until  the	file  is  found	 or  the  root
	   directory  is  reached  or  the directory is	located	on a different
	   file	system.	 (This last requirement	is to  prevent	problems  with
	   automounters	or hung	network	filesystems.)

	   For	 example,   if	 you  have  a  project	with  many  levels  of
	   subdirectories, you could include this common fragment  in  all  of
	   the makefiles (e.g.,	by using the "include" statement):

	       TOP_LEVEL_INCLUDE_DIR :=	$(find_upwards includes)
					   # Searches for a directory that contains the
					   # includes subdirectory.

	       %.o : %.c
		   $(CC) $(CFLAGS) -I$(TOP_LEVEL_INCLUDE_DIR) -c $(input) -o $(output)

	   Another  problem that "find_upwards"	can help solve is locating the
	   top-level directory of a build.  Often it is	 useful	 to  define  a
	   variable like this:

	       TOP := ../../..

	   if  you  have  some	important information located only in the top-
	   level directory.  But this is hard to maintain, because the	number
	   of  ".."  is	 different for different levels	of the directory tree.
	   Instead, you	can use	"find_upwards" to locate a file	which is known
	   to be present only  in  the	top  level  directory.	 Suppose,  for
	   example,  that  the file "LICENSE" is located only in the top level
	   directory.  Then you	could do this:

	       TOP := $(dir_noslash $(find_upwards LICENSE))

	   "$(find_upwards LICENSE)" returns the  full	path  of  the  license
	   file;  "$(dir_noslash ...)" strips off the filename,	returning only
	   the directory.

	   (Note that the "include" statement automatically  searches  upwards
	   for files, so there is no need to do	something like this:

	       include $(find_upwards top_level_rules.mk)

	   Instead, you	can just do

	       include top_level_rules.mk

	   and it will work just as well.)

	   If  the file	is not found, "find_upwards" will abort	the build with
	   an error message.

	   If you specify more than one	file, find_upwards will	search for the
	   first one, then the second one, and so on.  In other	words,

	       $(find_upwards file1 file2)

	   is equivalent to

	       $(find_upwards file1) $(find_upwards file2)

	   If  you  want  to  look  for	 any  one  of  the  files,  then   use
	   "find_first_upwards"	instead.

       find_first_upwards file1	file2 ...
	   This	 function  behaves  like "find_upwards"	except that it returns
	   the	first  file  of	 any  files  in	 the  list  that   it	finds.
	   Specifically,  it checks the	current	directory for any of the files
	   in the list,	and returns the	first file  which  exists  or  can  be
	   built.   If	none  of  the  files  exist  or	 can  be built in that
	   directory, it checks	.., then ../..,	etc., until it reaches	either
	   the	root  directory	or a directory which is	located	on a different
	   file	system.

       first_available file1 file2 ...
	   Return the first file in a list that	exists or can be built.	  This
	   can	be  useful  for	 adapting  your	 makefiles  to work on several
	   different machines  or  networks,  where  important	files  may  be
	   located  in	different places.  For example,	here's a line from one
	   of my makefiles:

	       TCL_LIB = $(first_available \
		   /usr/local/stow/tcl-8.4.5-nothread/lib/libtcl8.4.so \
		   /usr/lib/libtcl8.4.so /usr/lib/libtcl.so \
		   /net/na1/tcl8.4a3/lib/libtcl8.4.a \
		   /net/na1/tcl8.4a3/lib/libtcl8.4.sl)

	   This	line will check	for the	 Tcl  library  in  all	of  the	 above
	   places,  stopping at	the first one that it finds.  The link command
	   then	includes $(TCL_LIB) so we get the appropriate Tcl library.

       infer_linker file1 file2	...
	   Given a list	of object files	first build them if they have not been
	   yet.	 Then find whether they	depend on a Fortran, C++ or a C	source
	   and return the corresponding	compiler (which	better	knows  how  to
	   link	than "ld").

       infer_objects file1 file2 ..., pattern
	       $(infer_objects object1.o object2.o, *.o)

	   If you use standard conventions regarding header file names,	makepp
	   is  capable of guessing which ".o" or ".lo" files need to be	linked
	   with	your program.  I use this to pick out  files  from  a  library
	   directory  which  contains modules used in many different programs.
	   Instead of making a library ".a" file and having  the  linker  pick
	   out	the relevant modules, makepp can pick out the relevant modules
	   for you.  This way, only the	relevant modules get compiled.

	   Makepp's algorithm for inferring object dependencies	depends	on the
	   convention that the implementation  of  all	classes	 or  functions
	   defined  in	a header file "xyz.h" are compiled into	an object file
	   called "xyz.o" (or "xyz.lo").  So makepp's algorithm	for  inferring
	   object  dependencies	 starts	with one or a few objects that we know
	   have	to be linked into the program.	It looks at which  files  were
	   included  with  "#include"  in  those  sources,  and	 tries to find
	   corresponding object	files for each of the include files.

	   "$(infer_objects )" needs to	be mentioned in	the dependency list of
	   a program, like this:

	       myprog: $(infer_objects main.o another_object.o,	\
			   **/*.o /other/library/dirs/**/*.o)
		   $(CXX) $(inputs) -o $(output) $(LIBS)

	   The "$(infer_objects)" function takes two arguments (separated by a
	   comma, as shown).  The first	is one or a few	object files that  are
	   known  to be	required (wildcards are	permissible here).  The	second
	   is a	list of	possible objects (normally you would  use  a  wildcard
	   here)  that could be	linked in if necessary.	 The return value from
	   this	function is a list that	contains first all of the  objects  in
	   the	first  argument,  and then after those,	all additional objects
	   that	were contained in the second argument that are required	by the
	   objects in the first	argument.

	   For example,	suppose	"main.o" comes from "main.cpp",	which includes
	   "my_class.h".  "$(infer_objects)" looks for	files  with  the  name
	   "my_class.o".   If  exactly	one such file is found,	it is added to
	   the list.  (If two object files "my_class.o"	are found in different
	   directories,	a warning message is printed.)	 "infer_objects"  also
	   examines   "my_class.cpp"   to  see	what  it  includes,  and  what
	   additional object files are implied.

       mktemp
       mktemp prefix
       mktemp prefixXXX
       mktemp /
	   Returns  an	unpredictable  temporary  filename,  which  does   not
	   currently  exist.   No  name	 pointing to the same file is returned
	   twice, even with different relative paths, within  one  makepp  run
	   (except  possibly  with traditional recursive make, or if Perl code
	   running within a rule action	calls "f_mktemp").  At the end of  the
	   makepp run all files	returned by this function are deleted, if they
	   exist  (again  except  for  those returned by this function in Perl
	   code	running	within a rule).

	   Any number of upper case "X"s  at  the  end	of  the	 argument  are
	   replaced  by	 that  many random letters and digits.	The more there
	   are,	the less likely	this is	to collide with	other processes, so if
	   you give a prefix like "/tmp/abc.", you should  have	 enough	 "X"s.
	   If  there  is  more	than one X, the	first character	comes from the
	   process id.	If there are none, it is as  though  there  were  ten,
	   which  is  supposedly  enough  (8.4e17  possibilities  or 3.7e15 on
	   Windows).  If there is no argument, the prefix defaults  to	"tmp."
	   in the current directory.

	   Note	 that  you  don't want to give such a name as rule targets and
	   dependencies.  The  result  would  be  correct,  but	 it  would  be
	   recreated every time	you run	makepp.

	   Also,  as  it  is  always  different, you should use	this in	a rule
	   action only if you use ":build_check	ignore_action":

	       TMPFILE ;= $(mktemp)	   # 1 call; "=" would mean 3 calls: 3 files
	       A-count B-count:	:build_check ignore_action
		   produce-As-and-Bs >$(TMPFILE)
		   &grep -c /A/	$(TMPFILE) -o A-count
		   &grep -c /B/	$(TMPFILE) -o B-count

	   Or you should export	it and let the Shell evaluate it:

	       export TMPFILE ;= $(mktemp)
	       A-count B-count:
		   produce-As-and-Bs >$$TMPFILE	# makepp doesn't see the var value
		   fgrep -c A $$TMPFILE	>A-count
		   fgrep -c B $$TMPFILE	>B-count

	   The last form repeats the previous return value, so you can use  it
	   in a	pattern	rule:

	       %.x: %.y
		   &grep foo $(input) -o $(mktemp)
		   &sed	bar $(mktemp /)	-o $(output) # Operate on the output of	&grep

       notdir filenames
	   Returns   the  non-directory	 portion  of  the  filename(s),	 i.e.,
	   everything after the	last slash if  there  is  one,	or  the	 whole
	   filename otherwise.

       only_generated filenames
	   Returns  only  those	 filenames  in the list	that were generated by
	   makepp and not since	modified, according to the build info file.

	   This	function is useful in clean target  rules  (though  of	course
	   "makeppclean" is the	preferred variant):

	       $(phony clean):
		   &rm -f $(only_generated **/*)

       only_nontargets filenames
	   Returns  only  those	 filenames in the list that are	not targets of
	   any rule (either explicit or	pattern	rules).	  You  may  specify  a
	   wildcard  (see  the	"$(wildcard )"	function  for  more details on
	   makepp's  wildcards).   This	 can  be   used	  for	generating   a
	   distribution	target,	for example:

	       .PHONY: distribution

	       distribution:
		   &mkdir our_product-$(VERSION)
		   &cp $(filter-out %~,	$(only_nontargets *)) our_product-$(VERSION)
		   tar cf - our_product-$(VERSION) | gzip -9c >	our_product-$(VERSION).tar.gz

	   In  this case, the "$(only_nontargets *)" returns every file	in the
	   current  directory  that  is	 not  a	 target	 of  some  rule.   The
	   "$(filter_out %~, ...)"  removes editor backups.

	   Similar to "only_targets" (see above), "only_nontargets" only knows
	   about  targets  that	 have  been  defined  already.	This is	only a
	   problem if you use it to define variables with the ":=" assignment;
	   if you use it in the	dependency list	or in the body of a rule,  all
	   other rules will already have been seen.

       only_stale filenames
	   Returns  only  those	 filenames  in the list	that were generated by
	   makepp and not since	modified, according to the  build  info	 file,
	   but are no longer targets of	any rule.

	   This	function is useful for ensuring	that there are no dependencies
	   on such files, without forcing a clean build	of all of the targets:

	       $(phony flush):
		   &rm -f $(only_stale **/*)

	   Actually, it's probably better instead to write a script that calls
	   makepp  to  generate	 the  list  of stale files, and	then have that
	   script remove all of	the listed files that aren't  currently	 under
	   source  control,  just  in  case  a generated file becomes a	source
	   file. Makepp	doesn't	have such a function built in  because	makepp
	   is (and probably ought to remain) agnostic about source control.

       only_targets filenames
	   Returns  only those filenames in the	list that are actually targets
	   of some rule	(either	explicit or pattern rules).  You  may  specify
	   wildcards  (including  makepp's  special  wildcard,	"**")  in  the
	   filenames.  (See the	 "$(wildcard )"	 function  for	more  details.
	   This	can be used for	a clean	target,	for example:

	       .PHONY: clean

	       clean:
		   &rm -f $(only_targets *)

	   Now	if you type "makepp clean", it will delete everything it knows
	   how to build.  But don't create a clean target,  use	 "makeppclean"
	   instead!

	   Another place where it may be useful	is to avoid including stale .o
	   files  in  your  build.   For  example, if you build	a library like
	   this:

	       mylib.a:	*.o
		   &rm -f $(output)
		   $(AR) cr $(output) $(inputs)

	   and then you	delete some source files  but  forget  to  delete  the
	   corresponding  .o  files,  the .o files will	still be around.  This
	   means they will still be incorporated into the library despite  the
	   fact	 that  they  are not useful any	more.  If you modify your rule
	   like	this:

	       mylib.a:	$(only_targets *.o)
		   &rm -f $(output)
		   $(AR) cr $(output) $(inputs)

	   then	this problem won't occur.

	   Note	that this refers only to files that are	known to be targets at
	   the time you	invoke "only-targets".	If "only_targets"  appears  in
	   the	dependencies  or  actions of a rule, then all possible targets
	   will	be known because dependencies and actions  are	not  evaluated
	   until  the  rule  is	 executed.   However,  if  you evaluate	try to
	   evaluate it earlier in the makefile with a ":=" variable like this:

	       ALL_TARGETS := $(only_targets *)

	       target1:	dependency1
		   actions

	       target2:	dependency2
		   actions

	   then	"only_targets" will not	know about the subsequent rules.

	   Similarly, "only_targets" doesn't know about	 targets  produced  in
	   makefiles  that are loaded with recursive make.  (But you shouldn't
	   be  using  recursive	 make  anyway;	use  use  the  "load_makefile"
	   statement, or implicit makefile loading instead.)

       relative_filename file1 file2 file3[, slash]
	   Returns  the	 name of those files relative to the current directory
	   (the	one the	makefile is in).  This	can  also  be  used  to	 clean
	   unnecessary "./" and	other junk from	the path:

	       DIR := .
	       SUBDIR := ..
	       FNAME :=	$(DIR)/../otherdir/$(SUBDIR)/files
	       X := $(relative_filename	$(FNAME))

	   If  slash is	true (usually 1) the returned filenames	are guaranteed
	   to contain a	slash by prepending "./" if necessary, so that you can
	   use it as an	executable name	without	 worrying  about  the  command
	   search path overriding the directory	location.

	   If  the  path goes by the root directory, the parent	of either your
	   home	directory or the "$(ROOT)" of your build system, or on Windows
	   a drive's root (depending on	the environment, this also happens for
	   /cygdrive/c or /c), an absolute path	will be	returned instead.

       relative_to file1 file2 file3[, directory]
	   Returns  the	 name  of  those  files	 relative  to  the   specified
	   directory.	This  is typically useful when for whatever reason you
	   have	to execute a  command  from  a	different  directory  (default
	   current directory):

	       source_backup.tar:
		   cd .. && tar	cf $(relative_to $(output), ..)	$(relative_to ., ..)

       suffix names...
	   Extracts  the  suffix  of each file name in names. If the file name
	   contains a period, the suffix is everything starting	with the  last
	   period.  Otherwise, the suffix is the empty string. This frequently
	   means that the result will be empty when names is not, and if names
	   contains multiple file names, the result  may  contain  fewer  file
	   names.

	   For example,

	       $(suffix	src/foo.c src-1.0/bar.c	hacks)

	   produces the	result ".c .c".

       temporary words
	   Let	makepp	know  that the specified targets may be	removed	by the
	   rule	that generates them.  Similar to "phony", except  that	makepp
	   expects  that  a real file of that name will	may be affected	by the
	   rule.  A rule is not	executed if only  its  temporary  targets  are
	   out-of-date.

       wildcard	pattern
	   Returns  the	 sorted	 names of all files matching the given pattern
	   which exist,	or those files which do	not yet	exist but can be built
	   based on the	rules that makepp knows	about at  the  point  when  it
	   evaluates  the expression.  In this last point it differs from rule
	   input wildcards, which apply	even to	files created by  rules	 found
	   later.

	   Makepp supports all the usual shell wildcards ("*", "?", and	"[]").
	   It also has a wildcard "**" which matches any number	of intervening
	   directories.	  (This	 idea  was  stolen  from  zsh.)	  For example,
	   "**/*.c" matches all	the  .c	 files	in  the	 entire	 source	 tree.
	   "objects/**/*.o" matches all	the .o files contained anywhere	in the
	   subdirectory	 objects  or any of its	subdirectories or any of their
	   subdirectories.  The	"**" wildcard will not follow  soft  links  to
	   directories	at any level, nor will it attempt to enter directories
	   which exist but cannot be read.  Also files and  directories	 which
	   exist but cannot be read will not be	returned by "$(wildcard	)".

   String Functions
       addprefix prefix, words
	   Prepends  the  prefix  string to each of the	words.	This is	mostly
	   for GNU make	compatibility; using rc-style expansion, this  can  be
	   done	in a more readable fashion like	this:

	       MODULES := a b c	d
	       X_OLD_STYLE := $(addprefix $(OBJDIR)/, $(addsuffix .o, $(MODULES)))
	       X_NEW_STYLE := $(OBJDIR)/$(MODULES).o   # Isn't that easier to read?

       addsuffix suffix, words
	   Appends the suffix string to	each of	the words.  This is mostly for
	   GNU	make compatibility; using rc-style expansion, this can be done
	   in a	more readable fashion like this:

	       X_OLD_STYLE := $(addsuffix .o, $(MODULES))
	       X_NEW_STYLE := $(MODULES).o

       call variable[, words]...
	   The function	"call" is unique in that it  can  be  used  to	regard
	   variable  as	 a  parameterized  function.  You can assign a complex
	   expression to variable and use "call" to  expand  its  contents  to
	   different  values  parametrized  by	words later on.	 In other make
	   systems, a variable that is used  mainly  for  the  purpose	to  be
	   expanded via	"call",	is called a macro.

	   During  expansion  of  the  macro,  the temporary variables $1, $2,
	   "..." refer to the arguments	given to "call"	during its invocation.
	   The variable	$0 will	be expanded to the name	 of  the  macro	 (i.e.
	   variable) that "call" is currently expanding.

	   There  is no	limit, how many	arguments a macro may be "call"ed with
	   or how many parameters a  macro  may	 expect.   If  you  pass  more
	   arguments to	"call" as the macro need, all exceeding	arguments will
	   be  discarded.  If you pass less arguments than a macro expect, all
	   exceeding parameters	collapse into the empty	string.

	   First a simple example:

	       rest = $(wordlist 2, $(words $(1)),$(1))
	       list = A	B C D E
	       butfirst	:= $(call rest,$(list))

	   Here, the variable "$(butfirst)" will contain the list "B C D E".

	   And now for a more complex example to show what is possible:

	       rest = $(wordlist 2,$(words $(1)),${1})
	       mymap = $(if $2,$(call $1,$(firstword $2)) $(call $0,$1,$(call rest,$2)))
	       downcase	= ${makeperl lc("$1")}

	       UCWORDS = ALL THESE WORDS ARE UPCASE
	       DCWORDS := $(call mymap,downcase,$(UCWORDS))

	   Now "$(DCWORDS)"  contains  "all these words	are upcase".   By  the
	   way:	 it  makes  no difference, whether we access the arguments via
	   $1, "${1}" or "$(1)"	within a macro.

	   You can directly use	the variable as	though it were a function,  if
	   there is no function	of that	name.  This is internally converted to
	   "call", so these are	equivalent:

	       discussion = The	$0 turned into $1 $2.
	       direct =	$(discussion an,argument)
	       called =	$(call discussion,an,argument)

	   It  might  seem  debatable whether "$[call]"	should also expand the
	   macro's "$[]" expressions, or whether a function should  always  do
	   the same thing, no matter how it is called.	The latter was chosen,
	   because  with  normal  make	syntax	it  would be impossible	to get
	   "$[1], $[2]..." into	a variable (they'd get	replaced  by  nothing,
	   before  the	assignment  even  takes	 place.)  Hence, if you	have a
	   macro for defining a	rule, you want expressions like	"$(output)" to
	   be seen when	the rule gets parsed, so you must  protect  them  from
	   "call":

	       define myrule
		   $2: $1
		       mycommand $$(input) -o $$(output)
	       endef
	       $[myrule	myinput,myoutput]

       filter patterns,	words
	   Returns  all	 words	in the list that match the patterns.  Patterns
	   may simply be other words, or filename wildcards (i.e.,  "*",  "?",
	   and	"[a-z]"	 are  recognized),  or	they may have a	"%" character,
	   which means to match	any string at that point (same as "*").

       filter_out patterns, words
	   Returns all words in	the list  that	do  not	 match	the  patterns.
	   Patterns  may  simply  be other words, or filename wildcards	(i.e.,
	   "*",	"?", and "[a-z]" are recognized),  or  they  may  have	a  "%"
	   character,  which  means to match any string	at that	point (same as
	   "*").

	   For example:

	       libproduction.a:	$(filter_out test_*, $(wildcard	*.o))

	   will	put all	.o files which exist or	can  be	 built,	 except	 those
	   beginning with test_, into libproduction.a.

       findstring find,	in
	   Return find,	if it is a substring of	in.

       firstword words
	   Return the first word.

       map words, perlcode
       makemap words, perlcode
	   Similarly  to Perl's	map, applies perlcode to each word in turn and
	   returns the results.	 The first variant is plain Perl  code,	 while
	   the	second	variant	 first	passes the perlcode through Make-style
	   variable expansion.	The words are expanded in both cases.

	   The words are in $_ and are returned	unless you undef $_.  This  is
	   intended  for modifications not easily handled by "patsubst".  Only
	   the first comma is a	separator, any others are considered  part  of
	   the perlcode.

	       # Switch	words.	Double parens, to allow	parens in perlcode, or use ${}:
	       X = $((map $(VALUES), s/(.+)-(.+)/$2-$1/))
	       # You can use make expressions, but then	you must use $$	for Perl $:
	       Y = $(makemap $(VALUES),	tr/$(OLDCHARS)/$(NEWCHARS)/ or $$_ = 'failed')
	       # You can eliminate candidates:
	       Y = $(map $(VALUES), undef $_ if	/no_good/)

       join words1, words2
	   Do a	pairwise join of the first words and the second	words.

       patsubst	pattern, substitute, words
	   Performs  a	substitution  on  each	word  in the word list.	 A "%"
	   character matches any string.   This	 is  best  illustrated	by  an
	   example:

	       OBJS = $(patsubst %.c, object_dir/%.o, $(C_SOURCES))

	   takes  every	 file  in  C_SOURCES and returns the name of an	object
	   file	in  object_dir.	  Sometimes  it	 is  more  concise  to	use  a
	   substitution	reference, e.g., the above could have been written as

	       OBJS = $(C_SOURCES:%.c=object_dir/%.o)

       sort word1 word2	word3 ...
	   Sorts the words in lexical order and	removes	duplicates.

       strip string
	   Removes  leading  and  trailing whitespace from string and replaces
	   each	internal sequence of one or more whitespace characters with  a
	   single space. Thus, "$(strip	 a b  c	)" results in "a b c".

       subst from,to,text
	   Performs a textual replacement on the text text: each occurrence of
	   from	 is replaced by	to. The	result is substituted for the function
	   call. For example,

	       $(subst ee,EE,feet on the street)

	   substitutes the string "fEEt	on the strEEt".

       word n,text
	   Returns the nth word	of text. The legitimate	values of n start from
	   1 at	the beginning or backwards from	-1 at the end. If n is	bigger
	   than	the number of words in text, the value is empty.

       wordlist	indexlist, words
       wordlist	firstindex, lastindex, words
	   In  the first form you supply a list	of indices (counting from 1 at
	   the beginning or backwards from -1 at the end) to select the	 words
	   you	want.	In  the	second form you	specify	the range of words you
	   want	returned.

       words text
	   Returns the number of words in text.

   Miscellaneous Functions
       foreach var,list,text
	   The first two arguments, var	and list, are expanded before anything
	   else	is done; note that the last argument, text, is not expanded at
	   the same time. Then for each	word of	the expanded  value  of	 list,
	   the	variable  named	 by  the  expanded value of var	is set to that
	   word, and text is expanded. Presumably text contains	references  to
	   that	variable, so its expansion will	be different each time.

	   This	 simple	 example  sets	the  variable files to the list	of all
	   files in the	directories in the list	dirs:

	       dirs := a b c d
	       files :=	$(foreach dir,$(dirs),$(wildcard $(dir)/*))

	   Here	text is	"$(wildcard $(dir)/*)".	The first repetition finds the
	   value XaX for dir, so it produces the same  result  as  "$(wildcard
	   a/*)";  the	second	repetition  produces the result	of "$(wildcard
	   b/*)"; and the third, that of "$(wildcard c/*)".

	   This	example	has the	same result (except for	setting	XdirsX)	as the
	   following example:

	       files :=	$(wildcard a/* b/* c/* d/*)

	   When	text is	complicated, you can improve readability by giving  it
	   a name, with	an additional variable:

	       find_files = $(wildcard $(dir)/*)
	       dirs := a b c d
	       files :=	$(foreach dir,$(dirs),$(find_files))

	   Here	 we  use the variable find_files this way. We use plain	X=X to
	   define a recursively-expanding variable, so that its	value contains
	   an actual function call to  be  reexpanded  under  the  control  of
	   foreach;  a	simply-expanded	 variable would	not do,	since wildcard
	   would be called only	once at	the time of defining find_files.

	   Note: Don't confuse this with the "$(foreach)" special variable.

       info text
       warning text
       error text
	   Output text returning the nothing.  The first goes to  STDOUT,  the
	   second to STDERR, the third additionally aborts processing.

       prebuild	targets
       make targets
	   Returns  its	 argument  verbatim,  but  first  builds all the files
	   listed.  This is useful when	a given	file is	needed when evaluating
	   a make expression.  This typically happens when you	have  a	 build
	   where the set of files involved is computed by some shell commands.
	   For example,

	       file_list :
		   # shell commands to compute a list of files to put into the program

	       my_program : $(&cat $(prebuild file_list))

	   If  you  need  the  list  in	 more  than one	rule, it would be more
	   efficient to	use an expand at most once variable:

	       file_list ;= $(&cat $(prebuild file_list))

	       my_program1 : a.o $(file_list)

	       my_program2 : b.o $(file_list)

	   If instead you  specified  just  "$(&cat file_list)",  then	makepp
	   would  not  force file_list to be up-to-date	before it executes the
	   shell command.  Using "$(prebuild )"	is the best way	to solve  this
	   problem.  You might be tempted to try other things, like this:

	       my_program : file_list $(&cat file_list)

	   but this won't work because "$(&cat file_list)" is evaluated	before
	   makepp attempts to build "file_list".

       only_phony_targets names
	   Returns only	those names in the list	that are phony targets of some
	   rule	(either	explicit or pattern rules).  You may specify wildcards
	   (including makepp's special wildcard, "**") in the filenames.  (See
	   the "$(wildcard )" function for more	details.  This can be used for
	   grouping targets, for example:

	       $(phony tests): $(only_phony_targets */**/tests)

       origin variable
	   Given the name of a variable, tells you where its value comes from.

       perl perlcode
       makeperl	perlcode
	   Evaluates  perlcode	in  a block and	returns	the result.  The first
	   variant is plain Perl code, while the second	variant	 first	passes
	   the perlcode	through	Make-style variable expansion.

	   Note,  that,	as with	all functions, the function delimiter used may
	   not appear within the perlcode outside of single or	double	quoted
	   strings.  But you can double	it as in the last example:

	       VAR = 1
	       VAR1 = ${perl ($VAR + 1)	* 3}
	       VAR2 = $(perl do	{ $VAR *= 3; return $VAR + 1 } if $VAR)
	       VAR3 = $(makeperl $(VAR1) * 3 + $$VAR) #	one Make var and one Perl var
	       VAR = $((perl if( ... ) { ... }))

       phony words
	   Indicates  that  the	 list of words are actually phony targets, and
	   returns the list of targets.	 It's intended to be used like this:

	       $(phony all): my_program

	       $(phony clean):
		   &rm -f *.o my_program

	   You can also	declare	one or more targets as phony with a line  like
	   this	anywhere in your makefile:

	       .PHONY: all clean

       print text
	   Outputs  the	 text  and  returns  it.   This	 is  mostly useful for
	   debugging, when you don't understand	why variable substitution  has
	   the result that it does.  For example,

	       XYZ := $(print $(patsubst %.c, %o, $(SOURCE_FILES)))

	   will	print out the result of	the "patsubst" call.

	       XYZ := $(patsubst %.c, %o, $(print $(SOURCE_FILES)))

	   will	print out the last argument to the "patsubst" call.

       shell shell-command
	   Returns  the	 output	 from  the  given shell	command, with newlines
	   replaced by spaces.

	   Note, that, as with all functions, the function delimiter used  may
	   not	appear	within	the  shell-command outside of single or	double
	   quoted strings.  But	you can	double it as in	the second example:

	       date = $(shell date)	   # better: $(perl scalar localtime)
	       VAR = ${{shell f() { echo hello;	}; f}}

       xargs command,arguments[,suffix[,length]]
	   Returns a newline-separated list of commands	that each  begin  with
	   the specified command, and end with as many elements	of the list as
	   possible without going over length (default 1000) characters.

	   The	purpose	 of  this is to	avoid spilling over the	command	length
	   limit on your system.  For example, if there	are a lot of generated
	   files, then you would probably want your clean  target  (which  you
	   should  not	have, because "makeppclean" is more efficient) to look
	   something like this:

	       $(phony clean):
		   $(xargs $(RM), $(only_targets **/*))

	   This	also  has  the	side-effect  that  no  command	whatsoever  is
	   generated  if  the  list  happens to	be empty.  But in this case it
	   would be better to use the builtin &rm, because  the	 arguments  to
	   the builtin commands	are only limited by Perl's memory:

	       $(phony clean):
		   &rm -f $(only_targets **/*)

	   If  a  third	argument is specified, then it is used to postfix each
	   command.  This is useful for	specifying redirectors,	 e.g.  (though
	   here	again &echo would help):

	       manifest:
		   &rm -f $@
		   &touch $@
		   $(xargs echo, $(only_nontargets **/*), >> $@)

       Some of this documentation is based on the GNU make documentation.

       Please	note   that   if   a  function	gets  called  during  makefile
       initialization, e.g.  the  expansion  of	 export	 variables,  error  or
       warning messages	will report line number	0.

AUTHOR
       Gary Holt (holt-makepp@gholt.net)

POD ERRORS
       Hey!  The  above	 document  had some coding errors, which are explained
       below:

       Around line 104:
	   Non-ASCII character seen before =encoding in	 'Xshort-circuitingX'.
	   Assuming UTF-8

perl v5.36.3			  2012-02-07		   MAKEPP_FUNCTIONS(1)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=makepp_functions&sektion=1&manpath=FreeBSD+Ports+14.3.quarterly>

home | help