符号管道'|'是什么意味着在 Makefile 中

What does the symbol pipe '|' means in a Makefile

来自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 的输入。

@MadScientist 的建议非常正确,但在这种特定情况下,我认为它不是用于传递参数,而是用于顺序调用这些命令。

这是我的理解(如有错误请指正)

This is where the variable is called: $$(call concat_cmd,$$(KERNEL))

1- concat_cmd 将调用 split_args 并将变量 KERNELbuild_cmd 传递给它:

define concat_cmd
$(call split_args,$(1),build_cmd)
endef

2- split_args 将用 space 替换 | 并调用 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 lzmabuild_cmd 将扩展为 Build/kernel-bin Build/ patch-cmdline ...

'|'还有另一种用法管道符号 - 定义仅提供程序目标排序而不是构建依赖项的仅顺序先决条件:

例如:

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)

参考:https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html