GNU 为多个目标制定规则

发布于 2024-09-02 10:50:01 字数 445 浏览 2 评论 0原文

我正在尝试让 GNU make 从单个输入生成多个输出。我可以演示的最简单的示例是:

a b : test
    cp $< $@

我认为应该将文件 test 复制到文件名 ab 中。但是,它只生成文件 a,在我看来,这与此处列出的说明相反:

http://www.gnu.org/software/automake/manual/make/Multiple-Targets.html

我做错了什么吗?

谢谢, 汤姆

I'm trying to get GNU make to produce multiple outputs from a single input. The most simple example I can demonstrate is:

a b : test
    cp 
lt; $@

which, I believe, should copy the file test to the files name a and b. However, it only makes the file a, which seems to me to be contrary to the instructions listed here:

http://www.gnu.org/software/automake/manual/make/Multiple-Targets.html

Am I doing something wrong?

Thanks,
Tom

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

月牙弯弯 2024-09-09 10:50:01

如果您运行依赖于 a 的规则,它将使用 $< 作为 test$@作为a。如果您运行依赖于 b 的规则,则 $@ 将改为 b。如果您在当前规则之上制定一条规则,例如:

all: a b

它将运行 ab 的规则,这是同一规则两次。否则,如果您的规则是文件中的第一个规则,它将仅使用第一个目标运行它,即 a

If you run a rule that depends on a, it will run your rule with $< as test and $@ as a. If you run a rule that depends on b, $@ will be b instead. If you make a rule above your current rule like:

all: a b

It will run the rules for a and b, which is that same rule twice. Otherwise, if your rule is the first in the file it will run it with the first target only, which is a

柠栀 2024-09-09 10:50:01

对@MichaelMrozek 的回答进行一点小小的澄清。

这:

a b : test
    cp 
lt; $@

与以下完全相同:

a : test
    cp 
lt; $@
b : test
    cp 
lt; $@

a 是文件中的第一个目标,因此它是默认目标。由于不依赖于 b,因此仅运行 a 的规则。

就像@MichaelMrozek所说,你可以添加另一个规则,或者你可以运行

make a b

A small clarification to @MichaelMrozek's answer.

This:

a b : test
    cp 
lt; $@

Is exactly the same as:

a : test
    cp 
lt; $@
b : test
    cp 
lt; $@

a is the first target in the file, so it's the default target. Only the rule for a runs, since there's no dependency on b.

Like @MichaelMrozek said, you can add another rule, or you can run

make a b
も星光 2024-09-09 10:50:01

一切都好。手册上说:

bigoutput littleoutput : text.g
        generate text.g -$(subst output,,$@) > $@

相当于

bigoutput : text.g
        generate text.g -big > bigoutput
littleoutput : text.g
  generate text.g -little > littleoutput

所以你的 Makefile 也相当于

a : test
    cp 
lt; $@
b : test
    cp 
lt; $@

当你输入命令“make”时,程序默认构建第一个目标,即“a”。

Everything is OK. The manual says :

bigoutput littleoutput : text.g
        generate text.g -$(subst output,,$@) > $@

is equivalent to

bigoutput : text.g
        generate text.g -big > bigoutput
littleoutput : text.g
  generate text.g -little > littleoutput

So your Makefile is also equivalent to

a : test
    cp 
lt; $@
b : test
    cp 
lt; $@

and when you'd entered the command 'make', the program defaulted to build the first target, i.e. 'a'.

反目相谮 2024-09-09 10:50:01

在此示例中:

a b : test
    cp 
lt; $@

Make 将 a 和 b 视为两个单独的配方。然而,在更高版本的 make 中有一个称为“分组目标”的功能。你可以写:

a b &: test
    cp 
lt; $@

它会按你的预期工作。或者,您可以使用哨兵/见证文件:

a_and_b : test
    cp 
lt; $@
    touch a_and_b

您需要一些额外的代码来删除哨兵,以防 a 和/或 b 被删除等...,它在 make 手册中有详细描述。
如果 a 和 b 的名称中有一些共同的模式,您也可以使用模式规则。即使在非常旧的 make 版本中,它们也完全满足了您的需要,但前提是目标可以用模式来描述。

In this example:

a b : test
    cp 
lt; $@

Make treats a and b as two separate recipes. There is however a feature called "grouped targets" in later versions of make. You can write:

a b &: test
    cp 
lt; $@

And it will work as you expected. Alternatively, you can use a sentinel / witness file:

a_and_b : test
    cp 
lt; $@
    touch a_and_b

You need some extra code to remove the sentinel in case a and/or b were deleted etc..., it's well described in the make manual.
If a and b have some common pattern in their names, you can also use pattern rules. They did exactly what you need, even in very old make versions, but only if the targets can be described with a pattern.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文