如何从变量生成makefile目标?

时间:2011-11-22 09:27:22

标签: makefile parallel-processing gnu

我目前有一个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)文件合并结果的目标。

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

3 个答案:

答案 0 :(得分:0)

你想要这样的东西吗?

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

.PHONY: default
default: $(TARGET)

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

%.out: %.txt
    cp $< $@

尝试-j的{​​{1}}选项,但是对于这样一个简单的例子,很容易解决依赖关系并并行构建。

答案 1 :(得分:0)

这里有几件事:

  • 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>

答案 2 :(得分:0)

您可以尝试使用vpath来查找输入文件。然后,您可以使用文件名而不使用目录部分。这样的事情应该有效。 ($(sort ...)用于删除重复项;并非绝对必要。)

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

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

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

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

此解决方案依赖于没有重复的文件名,但我认为您通过创建符号链接来暗示这种情况。