符号‘|’代表什么表示在 Makefile 中

问题描述 投票:0回答:3

来自 target/linux/ar71xx/image/Makefile

KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma

您能否帮我理解这一行的含义,并提供一个有关如何在 Makefile 中使用符号管道

|
的示例

makefile openwrt
3个回答
7
投票

这一行只是将 make 变量

KERNEL
设置为字符串
kernel-bin | patch-cmdline | lzma | uImage lzma
。管道符号 (
|
) 在这里没有特殊含义。

您必须了解如何使用该变量。它很可能出现在某个食谱中,如下所示:

foo:
       $(KERNEL)

在这种情况下,变量将被扩展并将结果发送到 shell。在 shell 中,管道符号导致左侧命令的标准输出连接到右侧命令的标准输入:它称为管道或管道数据。

这里有一个包含 4 个命令的管道:

kernel-bin
的输出被发送到
'patch-cmdline
的输入,
patch-cmdline
的输出被发送到
lzma
的输入,
lzma
的输出被发送到
uImage lzma
的输入。


6
投票

|
管道符号还有另一种用途 - 定义仅顺序先决条件,仅提供目标排序而不构建依赖关系:

例如:

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)

参考


1
投票

@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
...

© www.soinside.com 2019 - 2024. All rights reserved.