如何从变量生成 makefile 目标?

发布于 2024-12-17 18:14:03 字数 552 浏览 3 评论 0原文

我目前有一个 makefile 来处理一些数据。 makefile 通过获取 CONFIG 文件来获取数据处理的输入,该文件在变量中定义输入数据。目前,我将输入文件符号链接到本地​​目录,即 makefile 包含:

tmp/%.txt: tmp
    ln -fs $(shell echo $(INPUTS) | tr ' ' '\n' | grep $(patsubst tmp/%,%,$@)) $@

这不是非常优雅,但似乎可以工作。有更好的办法吗?基本上,给定

INPUTS = /foo/bar.txt /zot/snarf.txt

上面会将所有输入文件链接到 tmp/ 中,以便我可以使用类似规则处理它们

%.out: tmp/%.txt
    some command

以及根据所有 $(INPUT 合并结果的目标)文件。

此外,除了笨拙之外,makefile 无法与 -j 一起正常工作,这对于在合理的时间内完成分析至关重要。我猜这是 GNU make 中的一个错误,但欢迎任何提示。

I currently have a makefile to process some data. The makefile gets the inputs to the data processing by sourcing a CONFIG file, which defines the input data in a variable. Currently, I symlink the input files to a local directory, i.e. the makefile contains:

tmp/%.txt: tmp
    ln -fs $(shell echo $(INPUTS) | tr ' ' '\n' | grep $(patsubst tmp/%,%,$@)) $@

This is not terribly elegant, but appears to work. Is there a better way? Basically, given

INPUTS = /foo/bar.txt /zot/snarf.txt

The above will link all input files into tmp/, so that I can process them with rules like

%.out: tmp/%.txt
    some command

As well as targets to merge results depending on all $(INPUT) files.

Also, apart from the kludgosity, the makefile doesn't work correctly with -j, something that is crucial for the analysis to complete in reasonable time. I guess that's a bug in GNU make, but any hints welcome.

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

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

发布评论

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

评论(3

疧_╮線 2024-12-24 18:14:04

这里有几件事:

  • make 将处理输入列表。没有必要使用tr之类的。您可以使用 make 函数执行您想要的任何操作,例如 patsubst
  • make-j 配合良好。如果它没有按照你的预期工作,那么这意味着你没有在规则和依赖关系中表达你的全部想法。
  • 您写了有关合并输出的文章。上一颗子弹的原因可能就在这里。您必须指示 make 您的合并目标依赖于所有 .out 目标。然后,make 将在合并之前等待所有目标。
  • 我想不需要创建指向 .txt 源文件的符号链接。我非常确定您可以编写使用输入文件所在位置的模式规则。您必须允许输出文件位于各个子目录中。

最终会得到如下结果:

OUTPUTS = $(patsubst %.txt, out/%.out, $(INPUTS))

out/%.out: %.txt
    <some command>

merged: $(OUTPUTS)
    <merge command>

Several things here:

  • make will take care of the list of inputs. There's no need to use tr and such. You can do everything you want with make functions, such as patsubst.
  • make works well with -j. If it does not work as you expected, then it means that you didn't express all your mind in the rules and dependencies.
  • You wrote about merging your outputs. The cause of the previous bullet may be here. You have to instruct make that your merged target depend on all your .out targets. Then, make will wait for all targets before merging.
  • I guess there's no need to create symlinks to your .txt source files. I'm pretty sure you can write pattern rules that use the input files where they are. You have to allow the output files to be in various subdirectories.

It would end up with something along the lines of:

OUTPUTS = $(patsubst %.txt, out/%.out, $(INPUTS))

out/%.out: %.txt
    <some command>

merged: $(OUTPUTS)
    <merge command>
梦里°也失望 2024-12-24 18:14:04

您可以尝试使用 vpath 让 make 找到输入文件。然后,您可以简单地使用不带目录部分的文件名。像这样的东西应该有效。 ( $(sort ...) 用于删除重复项;并非绝对必要。)

INPUTS  := ...
OUTPUTS := $(patsubst %.txt, %.out, $(notdir $(INPUTS))

vpath %.txt $(sort $(dir $(INPUTS)))

merged.txt: $(OUTPUTS)
    <merge command> $^ -o $@

%.out: %.txt
    <some command> 
lt; -o $@

此解决方案依赖于不存在重复的文件名,但我认为您通过创建符号链接暗示了该条件。

You could try to use vpath to let make find the input files. You can then simply work with file names without the directory parts. Something like this should work. (The $(sort ...) is there to remove duplicates; not absolutely necessary.)

INPUTS  := ...
OUTPUTS := $(patsubst %.txt, %.out, $(notdir $(INPUTS))

vpath %.txt $(sort $(dir $(INPUTS)))

merged.txt: $(OUTPUTS)
    <merge command> $^ -o $@

%.out: %.txt
    <some command> 
lt; -o $@

This solution relies on there not being duplicate file names, but I think you implied that condition by creating the symlinks.

墨离汐 2024-12-24 18:14:03

你想要这样的东西吗?

TARGET = x
INPUT  = a.txt b.txt
OUTPUT = $(INPUT:%.txt=%.out)

.PHONY: default
default: $(TARGET)

$(TARGET): $(OUTPUT)
    cat $^ > $@

%.out: %.txt
    cp 
lt; $@

尝试使用 make-j 选项,但对于这样一个简单的示例,很容易解决依赖关系并并行构建。

You want something like this?

TARGET = x
INPUT  = a.txt b.txt
OUTPUT = $(INPUT:%.txt=%.out)

.PHONY: default
default: $(TARGET)

$(TARGET): $(OUTPUT)
    cat $^ > $@

%.out: %.txt
    cp 
lt; $@

Tried with the -j option to make, but for such a simple example it's easy to resolve the dependencies and build in parallel.

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