make: Eval Function
1
1 8.9 The 'eval' Function
1 =======================
1
1 The 'eval' function is very special: it allows you to define new
1 makefile constructs that are not constant; which are the result of
1 evaluating other variables and functions. The argument to the 'eval'
1 function is expanded, then the results of that expansion are parsed as
1 makefile syntax. The expanded results can define new 'make' variables,
1 targets, implicit or explicit rules, etc.
1
1 The result of the 'eval' function is always the empty string; thus,
1 it can be placed virtually anywhere in a makefile without causing syntax
1 errors.
1
1 It's important to realize that the 'eval' argument is expanded
1 _twice_; first by the 'eval' function, then the results of that
1 expansion are expanded again when they are parsed as makefile syntax.
1 This means you may need to provide extra levels of escaping for "$"
11 characters when using 'eval'. The 'value' function (⇒Value
Function) can sometimes be useful in these situations, to circumvent
1 unwanted expansions.
1
1 Here is an example of how 'eval' can be used; this example combines a
1 number of concepts and other functions. Although it might seem overly
1 complex to use 'eval' in this example, rather than just writing out the
1 rules, consider two things: first, the template definition (in
1 'PROGRAM_template') could need to be much more complex than it is here;
1 and second, you might put the complex, "generic" part of this example
1 into another makefile, then include it in all the individual makefiles.
1 Now your individual makefiles are quite straightforward.
1
1 PROGRAMS = server client
1
1 server_OBJS = server.o server_priv.o server_access.o
1 server_LIBS = priv protocol
1
1 client_OBJS = client.o client_api.o client_mem.o
1 client_LIBS = protocol
1
1 # Everything after this is generic
1
1 .PHONY: all
1 all: $(PROGRAMS)
1
1 define PROGRAM_template =
1 $(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%)
1 ALL_OBJS += $$($(1)_OBJS)
1 endef
1
1 $(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
1
1 $(PROGRAMS):
1 $(LINK.o) $^ $(LDLIBS) -o $@
1
1 clean:
1 rm -f $(ALL_OBJS) $(PROGRAMS)
1