来自 target/linux/ar71xx/image/Makefile
KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma
您能否帮我理解这一行的含义,并提供一个有关如何在 Makefile 中使用符号管道
|
的示例
这一行只是将 make 变量
KERNEL
设置为字符串 kernel-bin | patch-cmdline | lzma | uImage lzma
。管道符号 (|
) 在这里没有特殊含义。
您必须了解如何使用该变量。它很可能出现在某个食谱中,如下所示:
foo:
$(KERNEL)
在这种情况下,变量将被扩展并将结果发送到 shell。在 shell 中,管道符号导致左侧命令的标准输出连接到右侧命令的标准输入:它称为管道或管道数据。
这里有一个包含 4 个命令的管道:
kernel-bin
的输出被发送到 'patch-cmdline
的输入,patch-cmdline
的输出被发送到 lzma
的输入,lzma
的输出被发送到 uImage lzma
的输入。
|
管道符号还有另一种用途 - 定义仅顺序先决条件,仅提供目标排序而不构建依赖关系:
例如:
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir $(OBJDIR)
@MadScientist 的建议非常正确,但在这种特定情况下,我认为它不用于传递参数,而是用于顺序调用这些命令。
这是我的理解(如有错误请指正)
$$(call concat_cmd,$$(KERNEL))
1-
concat_cmd
将调用 split_args
并将变量 KERNEL
和 build_cmd
传递给它:
define concat_cmd
$(call split_args,$(1),build_cmd)
endef
2-
split_args
将用空格替换 |
并调用 build_cmd
,
define split_args
$(foreach data, \
$(subst |,$(space),\
$(subst $(space),^,$(1))), \
$(call $(2),$(strip $(subst ^,$(space),$(data)))))
endef
3- 最后,因为
KERNEL
被定义为 KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma
,所以 build_cmd
将扩展为 Build/kernel-bin
Build/ patch-cmdline
...