make: Foreach Function
1
1 8.5 The 'foreach' Function
1 ==========================
1
1 The 'foreach' function is very different from other functions. It
1 causes one piece of text to be used repeatedly, each time with a
1 different substitution performed on it. It resembles the 'for' command
1 in the shell 'sh' and the 'foreach' command in the C-shell 'csh'.
1
1 The syntax of the 'foreach' function is:
1
1 $(foreach VAR,LIST,TEXT)
1
1 The first two arguments, VAR and LIST, are expanded before anything else
1 is done; note that the last argument, TEXT, is *not* expanded at the
1 same time. Then for each word of the expanded value of LIST, the
1 variable named by the expanded value of VAR is set to that word, and
1 TEXT is expanded. Presumably TEXT contains references to that variable,
1 so its expansion will be different each time.
1
1 The result is that TEXT is expanded as many times as there are
1 whitespace-separated words in LIST. The multiple expansions of TEXT are
1 concatenated, with spaces between them, to make the result of 'foreach'.
1
1 This simple example sets the variable 'files' to the list of all
1 files in the directories in the list 'dirs':
1
1 dirs := a b c d
1 files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
1
1 Here TEXT is '$(wildcard $(dir)/*)'. The first repetition finds the
1 value 'a' for 'dir', so it produces the same result as '$(wildcard
1 a/*)'; the second repetition produces the result of '$(wildcard b/*)';
1 and the third, that of '$(wildcard c/*)'.
1
1 This example has the same result (except for setting 'dirs') as the
1 following example:
1
1 files := $(wildcard a/* b/* c/* d/*)
1
1 When TEXT is complicated, you can improve readability by giving it a
1 name, with an additional variable:
1
1 find_files = $(wildcard $(dir)/*)
1 dirs := a b c d
1 files := $(foreach dir,$(dirs),$(find_files))
1
1 Here we use the variable 'find_files' this way. We use plain '=' to
1 define a recursively-expanding variable, so that its value contains an
1 actual function call to be re-expanded under the control of 'foreach'; a
1 simply-expanded variable would not do, since 'wildcard' would be called
1 only once at the time of defining 'find_files'.
1
1 The 'foreach' function has no permanent effect on the variable VAR;
1 its value and flavor after the 'foreach' function call are the same as
1 they were beforehand. The other values which are taken from LIST are in
1 effect only temporarily, during the execution of 'foreach'. The
1 variable VAR is a simply-expanded variable during the execution of
1 'foreach'. If VAR was undefined before the 'foreach' function call, it
11 is undefined after the call. ⇒The Two Flavors of Variables
Flavors.
1
1 You must take care when using complex variable expressions that
1 result in variable names because many strange things are valid variable
1 names, but are probably not what you intended. For example,
1
1 files := $(foreach Esta-escrito-en-espanol!,b c ch,$(find_files))
1
1 might be useful if the value of 'find_files' references the variable
1 whose name is 'Esta-escrito-en-espanol!' (es un nombre bastante largo,
1 no?), but it is more likely to be a mistake.
1