|
|
| |
MAKEPP_FUNCTIONS(1) |
Makepp |
MAKEPP_FUNCTIONS(1) |
makepp_functions -- Functions in makepp
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.
- 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.
- 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 )".
- 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.
- 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.
Gary Holt (holt-makepp@gholt.net)
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
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |