Reputation: 1073
I am trying to make sense of the following lines in a GNU Makefile (modified to obscure proprietary stuff):
KERNEL_SEARCH := /lib/modules/$(shell uname -r)/build \
/usr/src/linux-headers-$(shell uname -r) \
/usr/src/linux
temp_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
KERNEL_SEARCH := $(foreach dir, $(K_SEARCH), $(temp_dir))
My understanding is that in the first line, KERNEL_SEARCH
is successively assigned each of the paths separated by \
. However, I am not sure what do the subsequent lines do? Can someone provide a quick explanation?
TIA
Vinod
Upvotes: 0
Views: 43
Reputation: 99094
Suppose the Make variable dir
has been given a value, say /usr/src/linux
. Now consider:
temp_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
This is a Make statement that constructs the line
[ -e /usr/src/linux/include/linux ] && echo /usr/src/linux
then passes it to the shell, then stores the result in the variable temp_dir
.
The fist part, in the brackets, is a shell conditional, which tests the existence of that file. The second part is a simple echo
statement which prints something to the screen. The &&
in the middle is a boolean AND
; if the first part evaluates as False, then evaluation stops, but if the first part evaluates as True, then the shell proceeds to the second part. So if the dir
contains include/linux
, then the shell will print the dir
, otherwise it will do nothing.
So if the directory named by dir
contains include/linux
, then temp_dir
will contain the value of dir
, otherwise temp_dir
will wind up empty.
Now consider:
KERNEL_SEARCH := ...
The variable KERNEL_SEARCH
contains a list. It is not successively assigned various things, it's just a list, a long string with some spaces in it. (I'd show you what it looks like, but that depends on the shell, and it would be kind of cryptic.) Those backslashes (\
) are there just to allow wrapping of the long line, to make the makefile easier to read.
Now the last line:
KERNEL_SEARCH := $(foreach dir, $(K_SEARCH), $(temp_dir))
I strongly suspect that you got the variable names swapped when you were obfuscating the code. I'll swap them back:
K_SEARCH := $(foreach dir, $(KERNEL_SEARCH), $(temp_dir))
The foreach
directive takes three arguments. Roughly, the first is a variable name, the second is a list, and the third is something to be expanded. Make iterates over the list, and for each word in the list it assigns that word to the variable, and expands the third argument. In this case, for each directory in $(KERNEL_SEARCH)
, Make expands $(temp_dir)
and gets either the name of the directory, or nothing.
So the result is a list of those directories (from the original list) which contain include/linux
.
Upvotes: 1