具有共享相同配方的多个规则的Makefile

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

我想知道是否可以编写一个包含多个规则的 Makefile,每个规则都定义自己的先决条件,并以相同的配方执行所有这些规则,而无需重复配方。示例:

TARGETS= file1 file2 file3

all: $(TARGETS)

file1: dep1 dep2
file2: dep2 dep3 dep4
file3: dep2 dep1
    cat $^ > $@

谢谢!

makefile rules
2个回答
64
投票

是的,写得相当明显:

TARGETS= file1 file2 file3

all: $(TARGETS)

file1: dep1 dep2
file2: dep2 dep3 dep4
file3: dep2 dep1

$(TARGETS):
    cat $^ > $@

UPD。

只是为了澄清。

通用制定规则看起来像这样:

targets... : prerequisites...
    recipe
    ...

规则的任何部分都可以省略。如果没有配方,人们可以在 makefile 中的任何位置填充先决条件列表,目标可以出现在多个规则语句的左侧。

例如,以下内容与上面的示例等效(假设 Makefile 设计正确,因此先决条件的顺序并不重要):

file1 file3       : dep1
file1 file2 file3 : dep2
file2             : dep3 dep4

与列出先决条件不同,每个目标最多可以有一个显式配方。在配方中,您可以使用自动变量来获取目标名称、先决条件列表等。

UPD。 2

正如@Calmarius 在评论中提到的那样,这不适用于模式规则,例如

%.txt: %.foo
。 目标中的多个模式意味着该规则立即产生所有这些目标。

此模式规则有两个目标:

%.tab.c %.tab.h: %.y
    bison -d $<

这告诉make,配方

bison -d x.y
将同时制作
x.tab.c
x.tab.h
。 如果文件 foo 依赖于 文件
parse.tab.o
scan.o
以及文件 scan.o 取决于 文件
parse.tab.h
,当
parse.y
更改时,配方
bison -d parse.y
只会执行一次,并且两者的先决条件
parse.tab.o
scan.o
会很满意。

尽管可以在模式规则中定义多个先决条件(也就是说,只要其目标包含

%
词干,否则它将是常规规则)。


0
投票

我发现了一种 GNU make 4.0 的模块化方法:

如果你像这样小心地定义你的命令

CMD_DBG=@echo "Making $@ from $<"

即使在这样的模式规则中,您也可以使用这些命令:

%.xml:  %.out
        $(CMD_DBG)

我什至在这里使用了一些病态的案例:

%.prtg: %.test
        $(CMD_DBG)
        @if cp -p "$<" "$@"; then \
            $(CMD_LINT_PRTG); \
        else \
            $(CMD_BAD_TGT); \
        fi

只要确保在定义命令时不使用

:=
知道你在做什么!

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