$(foreach _app,$(NDK_APPS),\
$(eval include $(BUILD_SYSTEM)/setup-app.mk)\
)
具体的操作还得进入setup-app.mk的内部。
首先展开eval函数的参数,然后以Makefile的句法解析该参数,故整个过程有两次展开,需要两个dollar符。
The foreach
function is very different from other functions. It causes one piece of text to be used repeatedly, each time with a different substitution performed on it. It resembles the for
command in the shell sh
and the foreach
command in the C-shell csh
.
The syntax of the foreach
function is:
$(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.
The result is that text is expanded as many times as there are whitespace-separated words in list. The multiple expansions of text are concatenated, with spaces between them, to make the result of foreach
.
The eval
function is very special: it allows you to define new makefile constructs that are not constant; which are the result of evaluating other variables and functions. The argument to the eval
function is expanded, then the results of that expansion are parsed as makefile syntax. The expanded results can define new make
variables, targets, implicit or explicit rules, etc.
The result of the eval
function is always the empty string; thus, it can be placed virtually anywhere in a makefile without causing syntax errors.
It's important to realise that the eval
argument is expanded twice; first by the eval
function, then the results of that expansion are expanded again when they are parsed as makefile syntax. This means you may need to provide extra levels of escaping for “$” characters when using eval
. The value
function (see Value Function) can sometimes be useful in these situations, to circumvent unwanted expansions.
感觉很不明白,先看个文档中的例子:
PROGRAMS = server client server_OBJS = server.o server_priv.o server_access.o server_LIBS = priv protocol client_OBJS = client.o client_api.o client_mem.o client_LIBS = protocol # Everything after this is generic .PHONY: all all: $(PROGRAMS) define PROGRAM_template = $(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) ALL_OBJS += $$($(1)_OBJS) endef $(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog)))) $(PROGRAMS): $(LINK.o) $^ $(LDLIBS) -o $@ clean: rm -f $(ALL_OBJS) $(PROGRAMS)
The call
function is unique in that it can be used to create new parameterized functions. You can write a complex expression as the value of a variable, then use call
to expand it with different values.
The syntax of the call
function is:
$(call variable,param,param,...)
When make
expands this function, it assigns each param to temporary variables $(1)
, $(2)
, etc. The variable $(0)
will contain variable. There is no maximum number of parameter arguments. There is no minimum, either, but it doesn't make sense to use call
with no parameters.
关键部分的展开结果为:
server : server.o server_priv.o server_access.o -lpriv -lprotocol
ALL_OBJS += server.o server_priv.o server_access.o