19.9. Functions
GNU make goes beyond simple macro expansion to provide functions
both built-in and user-defined functions. By using parameters, conditions, and built-in functions, you can define quite powerful functions and use them anywhere in your makefiles.
The syntax of function invocations in makefiles, like that of macro references, uses the dollar sign and parentheses:
$(function_name argument[,argument[,...]])
| Whitespace in the argument list is significant. make ignores any whitespace before the first argument, but if you include any whitespace characters before or after a comma, make treats them as part of the adjacent argument value. |
|
The arguments themselves can contain any characters, except for embedded commas. Parentheses must occur in matched pairs; otherwise they will keep make from parsing the function call correctly. If necessary, you can avoid these restrictions by defining a variable to hold a comma or parenthesis character, and using a variable reference as the function argument.
19.9.1. Built-in Functions
GNU make provides more than 20 useful text-processing and flow-control functions, which are listed briefly in the following sections.
19.9.1.1. Text-processing functions
The text-processing functions listed here are useful in operating on the values of make variables, which are always sequences of characters:
$(subst find_text, replacement_text, original_text)
Expands to the value of original_text, except that each occurrence of find_text in it is changed to replacement_text.
$(patsubst find_pattern, replacement_pattern, original_text)
Expands to the value of original_text, except that each occurrence of find_pattern in it is changed to replacement_pattern. The find_pattern argument may contain a percent sign as a wildcard for any number of non-whitespace characters. If replacement_pattern also contains a percent sign, it is replaced with the characters represented by the wildcard in find_pattern. The patsubst function also collapses each unquoted whitespace sequence into a single space character.
$(strip original_text)
Removes leading and trailing whitespace, and collapses each unquoted internal whitespace sequence into a single space character.
$(findstring find_text, original_text)
Expands to the value of find_text, if it occurs in original_text; or to nothing if it does not.
$(filter find_patterns, original_text)
find_patterns is a whitespace-separated list of patterns like that in patsubst. The function call expands to a space-separated list of the words in original_text that match any of the words in find_patterns.
$(filter-out find_patterns, original_text)
Expands to a space-separated list of the words in original_text that do not match any of the words in find_patterns.
$(sort original_text)
Expands to a list of the words in original_text, in alphabetical order, without duplicates.
$(word n, original_text)
Expands to the nth word in original_text.
$(firstword original_text)
The same as $(word 1,original_text).
$(wordlist n, m, original_text)
Expands to a space-separated list of the nth through mth words in original_text.
$(words original_text)
Expands to the number of words in original_text.
19.9.1.2. Filename-manipulation functions
These functions operate on a whitespace-separated list of file or directory names, and expand to a space-separated list containing a processed element for each name in the argument:
$(dir filename_list)
Expands to a list of the directory parts of each filename in the argument.
$(notdir filename_list)
Expands to a list of the filenames in the argument with their directory parts removed.
$(suffix filename_list)
Expands to a list of the filename suffixes in the argument. Each suffix is the filename ending, beginning with the last period (.) in it; or nothing, if the filename contains no period.
$(basename filename_list)
Expands to a list of the filenames in the argument with their suffixes removed. Directory parts are unchanged.
$(addsuffix suffix,filename_list)
Expands to a list of the filenames in the argument with suffix appended to each one. (suffix is not treated as a list, even if it contains whitespace.)
$(addprefix prefix,filename_list)
Expands to a list of the filenames in the argument with prefix prefixed to each one. (prefix is not treated as a list, even if it contains whitespace.)
$(join prefix_list,suffix_list)
Expands to a list of filenames composed by concatenating each word in prefix_list with the corresponding word in suffix_list. If the lists have different numbers of elements, the excess elements are included unchanged in the result.
$(wildcard glob)
Expands to a list of existing filenames that match the pattern glob, which typically contains shell wildcards.
19.9.1.3. Conditions and flow control functions
The functions listed here allow you to perform operations conditionally, process lists iteratively, or execute the contents of a variable:
$(foreach name, list, replacement)
The argument name is a name for a temporary variable (without dollar sign and parentheses). The replacement text typically contains a reference to $(name). The result of the function is a list of expansions of replacement, using successive elements of list as the value of $(name).
$(if condition, then_text[, else_text])
Expands to the value of then_text if condition, stripped of leading and trailing spaces, expands to a nonempty text. Otherwise, the function expands to the value of else_text, if present.
$(eval text)
Treats the expansion of text as included makefile text.
19.9.1.4. Operations on variables
The argument variable_name in the descriptions that follow is just the name of a variable (without dollar sign and parentheses), not a reference to it. (Of course, you may use a variable reference to obtain the name of another variable, if you want.)
$(value variable_name)
Expands to the "raw" value of the variable named, without further expansion of any variable references it may contain.
$(origin variable_name)
Expands to one of the following values to indicate how the variable named was defined:
- undefined
- default
- environment
- environment override
- file
- command line
- override
- automatic
$(call variable_name, argument[, argument[,...]])
Expands the variable named, replacing numbered parameters in its expansion ($1, $2, and so on) with the remaining arguments. In effect, this built-in function allows you to create user-defined function-like macros. See the section "User-Defined Functions," later in this chapter.
19.9.1.5. System functions
The functions in the following list interact with make's environment:
$(shell text)
Passes the expansion of text to the shell. The function expands to the standard output of the resulting shell command.
$(error text)
make prints the expansion of text as an error message and exits.
$(warning text)
Like the error command, except that make doesn't exit. The function expands to nothing.
19.9.2. User-Defined Functions
You can define functions in the same way as simply expanded variables or macros, using the define directive or the := assignment operator. Functions in make are simply variables that contain numbered parameter references$1, $2, $3, and so onto represent arguments that you provide when you use the built-in function call to expand the variable.
In order for these parameters to be replaced with the arguments when make expands your user-defined
function, you have to pass the function name and arguments to the built-in make function call.
Example 19-5 defines the macro getmodulename to return a filename for a program module depending on whether the flag STATIC has been set, to indicate a statically linked executable, or left undefined, to indicate dynamic object linking.
Example 19-5. The user-defined function getmodulename
# A conditional assignment, just as a reminder that
# the user may define STATIC=1 or STATIC=yes on the command line.
STATIC ?=
# A function to generate the "library" module name:
# Syntax: $(call getmodulename, objectname, isstatic)
define getmodulename
$(if $2,$1,$(addsuffix .so,$(basename $1)))
endef
all: circle
circle: circle.o $(call getmodulename,circulararea.o,$(STATIC))
$(CC) -o $@ $^
ifndef STATIC
%.so: %.o
$(CC) -shared -o $@ $<
endif
The $(call ...) function expands the macro getmodulename either to the text circulararea.o, or, if the variable STATIC is not defined, to circulararea.so.
The rule to build the object file circulararea.o in Example 19-5 brings us to our next topic, as it illustrates another way to query the STATIC flag in another way: by means of the conditional directive ifndef.
|