关于特定 GNU Makefile 条目的问题
A question about specific GNU Makefile entry
我试图理解 GNU Makefile 中的以下几行(修改为隐藏专有内容):
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))
我的理解是,在第一行中,KERNEL_SEARCH
依次赋值了由\
分隔的各个路径。但是,我不确定后续行是做什么的?有人可以提供快速解释吗?
TIA
维诺德
假设 Make 变量 dir
已被赋予一个值,比如 /usr/src/linux
。现在考虑:
temp_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
这是构造行的 Make 语句
[ -e /usr/src/linux/include/linux ] && echo /usr/src/linux
然后传递给shell,然后把结果存入变量temp_dir
。
括号中的第一部分是 shell 条件语句,用于测试该文件是否存在。第二部分是一个简单的 echo
语句,它在屏幕上打印一些东西。中间的&&
是布尔值AND
;如果第一部分的计算结果为 False,则计算停止,但如果第一部分的计算结果为 True,则 shell 继续进行第二部分。因此,如果 dir
包含 include/linux
,则 shell 将打印 dir
,否则将不执行任何操作。
所以如果 dir
命名的目录包含 include/linux
,那么 temp_dir
将包含 dir
的值,否则 temp_dir
将变为空.
现在考虑:
KERNEL_SEARCH := ...
变量KERNEL_SEARCH
包含一个列表。它是不是先后分配了各种东西,它只是一个列表,一个很长的字符串,里面有一些空格。 (我会告诉你它的样子,但这取决于 shell,这有点神秘。)那些反斜杠 (\
) 只是为了让长行换行, 使 makefile 更易于阅读。
现在最后一行:
KERNEL_SEARCH := $(foreach dir, $(K_SEARCH), $(temp_dir))
我强烈怀疑您在混淆代码时交换了变量名。我会把它们换回来:
K_SEARCH := $(foreach dir, $(KERNEL_SEARCH), $(temp_dir))
The foreach
directive 接受三个参数。大致来说,第一个是变量名,第二个是列表,第三个是要扩展的东西。 Make 遍历列表,对于列表中的每个单词,它将该单词分配给变量,并扩展第三个参数。在这种情况下,对于 $(KERNEL_SEARCH)
中的每个目录,Make 扩展 $(temp_dir)
并获取目录名称,或者什么都不获取。
所以结果是包含 include/linux
.
的那些目录(来自原始列表)的列表
我试图理解 GNU Makefile 中的以下几行(修改为隐藏专有内容):
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))
我的理解是,在第一行中,KERNEL_SEARCH
依次赋值了由\
分隔的各个路径。但是,我不确定后续行是做什么的?有人可以提供快速解释吗?
TIA
维诺德
假设 Make 变量 dir
已被赋予一个值,比如 /usr/src/linux
。现在考虑:
temp_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
这是构造行的 Make 语句
[ -e /usr/src/linux/include/linux ] && echo /usr/src/linux
然后传递给shell,然后把结果存入变量temp_dir
。
括号中的第一部分是 shell 条件语句,用于测试该文件是否存在。第二部分是一个简单的 echo
语句,它在屏幕上打印一些东西。中间的&&
是布尔值AND
;如果第一部分的计算结果为 False,则计算停止,但如果第一部分的计算结果为 True,则 shell 继续进行第二部分。因此,如果 dir
包含 include/linux
,则 shell 将打印 dir
,否则将不执行任何操作。
所以如果 dir
命名的目录包含 include/linux
,那么 temp_dir
将包含 dir
的值,否则 temp_dir
将变为空.
现在考虑:
KERNEL_SEARCH := ...
变量KERNEL_SEARCH
包含一个列表。它是不是先后分配了各种东西,它只是一个列表,一个很长的字符串,里面有一些空格。 (我会告诉你它的样子,但这取决于 shell,这有点神秘。)那些反斜杠 (\
) 只是为了让长行换行, 使 makefile 更易于阅读。
现在最后一行:
KERNEL_SEARCH := $(foreach dir, $(K_SEARCH), $(temp_dir))
我强烈怀疑您在混淆代码时交换了变量名。我会把它们换回来:
K_SEARCH := $(foreach dir, $(KERNEL_SEARCH), $(temp_dir))
The foreach
directive 接受三个参数。大致来说,第一个是变量名,第二个是列表,第三个是要扩展的东西。 Make 遍历列表,对于列表中的每个单词,它将该单词分配给变量,并扩展第三个参数。在这种情况下,对于 $(KERNEL_SEARCH)
中的每个目录,Make 扩展 $(temp_dir)
并获取目录名称,或者什么都不获取。
所以结果是包含 include/linux
.