=head1 NAME
makepp_functions -- Functions in makepp
=
for
vc
$Id
: makepp_functions.pod,v 1.48 2012/06/09 20:43:14 pfeiffer Exp $
=head1 DESCRIPTION
=
for
genindex
'\w+'
makepp_functions.pod
B<A:>E<nbsp>L<absolute_filename|/absolute_filename_files>,
L<absolute_filename_nolink|/absolute_filename_nolink_files>,
L<abspath|/absolute_filename_files>,
L<addprefix|/addprefix_prefix_words>,
L<addsuffix|/addsuffix_suffix_words>,
L<and|/and_condition1_condition2_condition3>,E<nbsp>
B<B:>E<nbsp>L<basename|/basename_filenames>,E<nbsp>
B<C:>E<nbsp>L<call|/call_variable_words>,E<nbsp>
B<D:>E<nbsp>L<dir|/dir_filenames>,
L<dir_noslash|/dir_noslash_filename>,E<nbsp>
B<E:>E<nbsp>L<error|/info_text>,E<nbsp>
B<F:>E<nbsp>L<filesubst|/filesubst_pattern_substitute_words>,
L<filter|/filter_patterns_words>,
L<filter_out|/filter_out_patterns_words>,
L<filter_out_dirs|/filter_out_dirs_filenames>,
L<findfile|/findfile_filename_path>,
L<find_first_upwards|/find_first_upwards_file1_file2>,
L<find_program|/find_program_name>,
L<findstring|/findstring_find_in>,
L<find_upwards|/find_upwards_filename>,
L<first_available|/first_available_file1_file2>,
L<firstword|/firstword_words>,
L<
foreach
|/foreach_var_list_text>,E<nbsp>
B<I:>E<nbsp>L<
if
|/if_string_result_if_string_not_blank_result_if_string_blank>,
L<iftrue|/if_string_result_if_string_not_blank_result_if_string_blank>,
L<infer_linker|/infer_linker_file1_file2>,
L<infer_objects|/infer_objects_file1_file2_pattern>,
L<info|/info_text>,E<nbsp>
B<J:>E<nbsp>L<
join
|/join_words1_words2>,E<nbsp>
B<M:>E<nbsp>L<make|/prebuild_targets>,
L<makemap|/map_words_perlcode>,
L<makeperl|/perl_perlcode>,
L<
map
|/map_words_perlcode>,
L</mktemp>,E<nbsp>
B<N:>E<nbsp>L<notdir|/notdir_filenames>,E<nbsp>
B<O:>E<nbsp>L<only_generated|/only_generated_filenames>,
L<only_nontargets|/only_nontargets_filenames>,
L<only_phony_targets|/only_phony_targets_names>,
L<only_stale|/only_stale_filenames>,
L<only_targets|/only_targets_filenames>,
L<or|/or_condition1_condition2_condition3>,
L<origin|/origin_variable>,E<nbsp>
B<P:>E<nbsp>L<patsubst|/patsubst_pattern_substitute_words>,
L<perl|/perl_perlcode>,
L<phony|/phony_words>,
L<prebuild|/prebuild_targets>,
L<
print
|/print_text>,E<nbsp>
B<R:>E<nbsp>L<realpath|/absolute_filename_nolink_files>,
L<relative_filename|/relative_filename_file1_file2_file3_slash>,
L<relative_to|/relative_to_file1_file2_file3_directory>,E<nbsp>
B<S:>E<nbsp>L<shell|/shell_shell_command>,
L<
sort
|/sort_word1_word2_word3>,
L<strip|/strip_string>,
L<subst|/subst_from_to_text>,
L<suffix|/suffix_names>,E<nbsp>
B<T:>E<nbsp>L<temporary|/temporary_words>,E<nbsp>
B<W:>E<nbsp>L<warning|/info_text>,
L<wildcard|/wildcard_pattern>,
L<word|/word_n_text>,
L<wordlist|/wordlist_indexlist_words>,
L<words|/words_text>,E<nbsp>
B<X:>E<nbsp>L<xargs|/xargs_command_arguments_suffix_length>
Any expression of the
format
C<$(name)>, where C<name> is not the name of a
variable, or S<C<$(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 C<name> is preceded by C<&> it runs the L<builtin
command|makepp_builtins> or script of that name within the makepp process, and
returns the standard output. This requires perl to be built
for
PerlIO. If
the name does not name a function it is transformed to an invocation of
L<call|/call_variable_words>.
As
with
variables you have a choice of C<$(name ...)> or C<${name ...}>. Where
the arguments contain these signs, either
use
the other, or double it as in
C<$((name ...() ))>. Doubling is also useful
if
you need the arguments to
span several lines. The newlines are then treated as spaces, except maybe in
C<define>. There is also the syntax C<$[name ...]> or C<$[[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 C<
sub
> statement and the section on L<extending
makepp|makepp_extending>
for
more details.
=head2 Conditional Functions
=over 4
=item and I<condition1[,condition2[,condition3...]]>
The and function provides a “short-circuiting” 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.
=item
if
I<string, result-
if
-string-not-blank[, result-
if
-string-blank]>
=item iftrue I<string, result-
if
-string-true[, result-
if
-string-false]>
An alternative to the C<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 C<-g -Wall>
if
the variable CC is either C<gcc> or
C<egcc>, and C<-g> otherwise. (This is what the
default
build rules
do
.)
C<iftrue> is similar to C<
if
>, except that the string C<0> is treated as
blank.
=item or I<condition1[,condition2[,condition3...]]>
The or function provides a “short-circuiting” 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.
=back
=head2 File and Filename Functions
=over 4
=item absolute_filename I<files>
=item abspath I<files>
Converts relative filenames into absolutes without F<.> or F<..>. For
example, S<C<$(absolute_filename xyz.c)>> might
return
C</usr/src/our_project/subdir/xyz.c>.
=item absolute_filename_nolink I<files>
=item realpath I<files>
Like L<absolute_filename|/absolute_filename_files>, but ensures that symbolic links
are resolved.
=item basename I<filenames>
The basename is the entire file name (
with
the directory), minus the text
after
and including the
last
period. E.g., S<C<$(basename
myfile/version-1.0-module.c)>> is C<myfile/version-1.0-module>
=item dir I<filenames>
Extracts the directory part of
each
file in the filename list, including the
trailing slash. Returns C<./>
if
there is
no
directory in the filename.
=item dir_noslash I<filename>
Same as S<C<$(dir )>> except that it doesn't
return
the trailing slash.
=item filesubst I<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.
=item filter_out_dirs I<filenames>
Returns all filenames that
do
not refer to directories.
=item findfile I<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 F<tcl.h> by searching all of the above
directories. The absolute path to the file is returned. Then
S<C<$(dir_noslash )>> extracts that directory, and it is put into the
include path.
=item find_program I<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)
F77 = $(find_program f77 g77 fort77)
CXX = $(find_program g++ c++ pg++ cxx CC aCC)
If none of the programs is found, S<C<$(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.
=item find_upwards I<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
C<include> statement):
TOP_LEVEL_INCLUDE_DIR := $(find_upwards includes)
%.o : %.c
$(CC) $(CFLAGS) -I$(TOP_LEVEL_INCLUDE_DIR) -c $(input) -o $(output)
Another problem that C<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 C<..> is
different
for
different levels of the directory tree. Instead, you can
use
C<find_upwards> to locate a file which is known to be present only
in the top level directory. Suppose,
for
example, that the file
C<LICENSE> is located only in the top level directory. Then
you could
do
this:
TOP := $(dir_noslash $(find_upwards LICENSE))
S<C<$(find_upwards LICENSE)>> returns the full path of the license file;
S<C<$(dir_noslash ...)>> strips off the filename, returning only the directory.
(Note that the C<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, C<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
C<find_first_upwards> instead.
=item find_first_upwards I<file1 file2 ...>
This function behaves like C<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 F<..>, then
F<../..>, etc.,
until
it reaches either the root directory or a
directory which is located on a different file
system
.
=item first_available I<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.
=item infer_linker I<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 C<ld>).
=item infer_objects I<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 C<.o> or C<.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 C<.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
C<xyz.h> are compiled into an object file called C<xyz.o> (or C<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
C<
corresponding object files
for
each
of the include files.
S<C<$(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 L<C<$(infer_objects)>|makepp_functions/infer_objects_file1_file2_pattern>
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 C<main.o> comes from C<main.cpp>, which includes
C<my_class.h>.
L<C<$(infer_objects)>|makepp_functions/infer_objects_file1_file2_pattern>
looks
for
files
with
the name C<my_class.o>. If exactly one such file is
found, it is added to the list. (If two object files C<my_class.o> are found
in different directories, a warning message is printed.) C<infer_objects>
also examines C<my_class.cpp> to see what it includes, and what additional
object files are implied.
=item mktemp
=item mktemp I<prefix>
=item mktemp I<prefix>XXX
=item 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
C<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 C<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
"F</tmp/abc.>"
,
you should have enough C<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
"F<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.
=begin comment
The C<temporary> function may
do
what you want in this case:
TMPFILE ;= $(temporary $(mktemp))
A-count: $(TMPFILE)
&grep
-c /A/ $(input) -o $(output)
B-count: $(TMPFILE)
&grep
-c /B/ $(input) -o $(output)
$(TMPFILE):
produce-As-and-Bs >$(output)
=end comment
Also, as it is always different, you should
use
this in a rule action only
if
you
use
C<:build_check ignore_action>:
TMPFILE ;= $(mktemp)
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
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)
=item notdir I<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.
=item only_generated I<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 C<makeppclean>
is the preferred variant):
$(phony clean):
&rm
-f $(only_generated **/*)
=item only_nontargets I<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 S<C<$(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 C<$(only_nontargets *)> returns every file in the current
directory that is not a target of some rule. The C<$(filter_out %~, ...)>
removes editor backups.
Similar to C<only_targets> (see above), C<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 C<:=> assignment;
if
you
use
it in the
dependency list or in the body of a rule, all other rules will already
have been seen.
=item only_stale I<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.
=item only_targets I<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, C<**>) in the filenames. (See the
S<C<$(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 S<C<makepp clean>>, it will
delete
everything it knows how to
build. But don't create a clean target,
use
C<makeppclean> instead!
Another place where it may be useful is to avoid including stale F<.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
F<.o> files, the F<.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 I<at
the
time
you invoke> C<only-targets>. If C<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 C<:=> variable like this:
ALL_TARGETS := $(only_targets *)
target1: dependency1
actions
target2: dependency2
actions
then C<only_targets> will not know about the subsequent rules.
Similarly, C<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 C<load_makefile> statement, or
L<implicit makefile loading|makepp_build_algorithm/Implicit loading>
instead.)
=item relative_filename I<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 C<./> and other
junk from the path:
DIR := .
SUBDIR := ..
FNAME := $(DIR)/../otherdir/$(SUBDIR)/files
X := $(relative_filename $(FNAME))
If I<slash> is true (usually C<1>) the returned filenames are guaranteed to
contain a slash by prepending C<./>
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 C<$(ROOT)> of your build
system
, or on Windows a drive's root
(depending on the environment, this also happens
for
F</cygdrive/c> or F</c>),
an absolute path will be returned instead.
=item relative_to I<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 ., ..)
=item suffix I<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 .c>.
=item temporary I<words>
Let makepp know that the specified targets may be removed by the rule
that generates them.
Similar to C<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.
=item wildcard I<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 L<rule input wildcards|makepp_rules/Wildcards>,
which apply even to files created by rules found later.
Makepp supports all the usual shell wildcards (C<*>, C<?>, and C<[]>). It
also
has
a wildcard C<**> which matches any number of intervening directories.
(This idea was stolen from zsh.) For example, C<**/*.c> matches all the F<.c>
files in the entire source tree. C<objects/**/*.o> matches all the F<.o>
files contained anywhere in the subdirectory F<objects> or any of its
subdirectories or any of their subdirectories. The C<**> 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 S<C<$(wildcard )>>.
=back
=head2 String Functions
=over 4
=item addprefix I<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
=item addsuffix I<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
=item call I<variable[, words]... X<call>>
The function C<call> is unique in that it can be used to regard I<variable> as
a parameterized function. You can assign a complex expression to I<variable>
and
use
C<call> to expand its contents to different
values
parametrized by
I<words> later on. In other make systems, a variable that is used mainly
for
the purpose to be expanded via C<call>, is called a B<macro>.
During expansion of the macro, the temporary variables B<C<$1>>, B<C<$2>>,
B<C<...>> refer to the arguments
given
to C<call> during its invocation. The
variable B<C<$0>> will be expanded to the name of the macro (i.e. I<variable>)
that C<call> is currently expanding.
There is
no
limit, how many arguments a macro may be C<call>ed
with
or how many
parameters a macro may expect. If you pass more arguments to C<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 C<$(butfirst)> will contain the list S<C<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 C<$(DCWORDS)> contains S<C<all these words are upcase>>. By the way: it
makes
no
difference, whether we access the arguments via B<C<$1>>, B<C<${1}>>
or B<C<$(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 C<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 C<$[call]> should also expand the macro's
C<$[]> 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 C<$[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 C<$(output)>
to be seen
when
the rule gets parsed, so you must protect them from C<call>:
define myrule
$2: $1
mycommand $$(input) -o $$(output)
endef
$[myrule myinput,myoutput]
=item filter I<patterns, words>
Returns all words in the list that match the patterns. Patterns may simply be
other words, or filename wildcards (i.e., C<*>, C<?>, and C<[a-z]> are
recognized), or they may have a C<%> character, which means to match any
string at that point (same as C<*>).
=item filter_out I<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., C<*>, C<?>, and C<[a-z]>
are recognized), or they may have a C<%> character, which means to match any
string at that point (same as C<*>).
For example:
libproduction.a: $(filter_out test_*, $(wildcard *.o))
will put all F<.o> files which exist or can be built, except those beginning
with
F<test_>, into F<libproduction.a>.
=item findstring I<find, in>
Return I<find>,
if
it is a substring of I<in>.
=item firstword I<words>
Return the first word.
=item
map
I<words, perlcode>
=item makemap I<words, perlcode>
Similarly to Perl's
map
, applies I<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 C<
$_
> and are returned
unless
you
undef
C<
$_
>. This is
intended
for
modifications not easily handled by C<patsubst>. Only the first
comma is a separator, any others are considered part of the I<perlcode>.
X = $((
map
$(VALUES), s/(.+)-(.+)/$2-$1/))
Y = $(makemap $(VALUES),
tr
/$(OLDCHARS)/$(NEWCHARS)/ or
$$_
=
'failed'
)
Y = $(
map
$(VALUES),
undef
$_
if
/no_good/)
=item
join
I<words1, words2>
Do a pairwise
join
of the first words and the second words.
=item patsubst I<pattern, substitute, words>
Performs a substitution on
each
word in the word list. A
C<%> 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
L<substitution reference|makepp_variables/Substitution References>, e.g.,
the above could have been written as
OBJS = $(C_SOURCES:%.c=object_dir/%.o)
=item
sort
I<word1 word2 word3 ...>
Sorts the words in lexical order and removes duplicates.
=item strip I<string>
Removes leading and trailing whitespace from string and replaces
each
internal
sequence of one or more whitespace characters
with
a single space. Thus,
C<$(strip a b c )> results in C<a b c>.
=item subst I<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 C<fEEt on the strEEt>.
=item word I<n,text>
Returns the I<n>th word of I<text>. The legitimate
values
of I<n> start from 1
at the beginning or backwards from -1 at the end. If I<n> is bigger than the
number of words in I<text>, the value is empty.
=item wordlist I<indexlist, words>
=item wordlist I<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.
=item words I<text>
Returns the number of words in I<text>.
=back
=head2 Miscellaneous Functions
=over 4
=item
foreach
I<var,list,text>
The first two arguments, I<var> and I<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 I<files> to the list of all files in the
directories in the list I<dirs>:
dirs := a b c d
files := $(
foreach
dir,$(dirs),$(wildcard $(dir)/*))
Here text is C<$(wildcard $(dir)/*)>. The first repetition finds the value ‘a’
for
dir, so it produces the same result as C<$(wildcard a/*)>; the second
repetition produces the result of C<$(wildcard b/*)>; and the third, that of
C<$(wildcard c/*)>.
This example
has
the same result (except
for
setting ‘dirs’) 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 ‘=’ 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 C<$(
foreach
)> special variable.
=item info I<text>
=item warning I<text>
=item error I<text>
Output text returning the nothing. The first goes to STDOUT, the second to
STDERR, the third additionally aborts processing.
=item prebuild I<targets>
=item make I<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 :
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 S<C<$(
&cat
file_list)>>, then makepp would not
force file_list to be up-to-date
before
it executes the shell command. Using
S<C<$(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 S<C<$(
&cat
file_list)>> is evaluated
before
makepp attempts to build C<file_list>.
=item only_phony_targets I<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, C<**>) in the filenames. (See the
S<C<$(wildcard )>> function
for
more details. This can be used
for
grouping
targets,
for
example:
$(phony tests): $(only_phony_targets */**/tests)
=item origin I<variable>
Given the name of a variable, tells you where its value comes from.
=item perl I<perlcode>
=item makeperl I<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
)
VAR = $((perl
if
( ... ) { ... }))
=item phony I<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
=item
print
I<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 C<patsubst> call.
XYZ := $(patsubst %.c,
%o
, $(
print
$(SOURCE_FILES)))
will
print
out the
last
argument to the C<patsubst>
call.
=item shell I<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)
VAR = ${{shell f() { echo hello; }; f}}
=item xargs I<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 I<
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
C<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 C<
&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 C<
&echo
>
would help):
manifest:
&rm
-f $@
&touch
$@
$(xargs echo, $(only_nontargets **/*), >> $@)
=back
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.
=head1 AUTHOR
Gary Holt (holt-makepp
@gholt
.net)