2011-11-22 101 views
1

我目前有一个makefile来处理一些数据。 makefile通过获取CONFIG文件来获取数据处理的输入,CONFIG文件定义了变量中的输入数据。目前,我输入文件的符号链接到本地​​目录,即生成文件包含:如何从变量生成makefile目标?

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

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

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

上面将全部输入文件链接到TMP /,这样我可以像

%.out: tmp/%.txt 
    some command 
的规则处理它们

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

此外,除了klugosity之外,makefile不能正确使用-j,这对分析在合理的时间内完成至关重要。我想这是GNU make的一个错误,但欢迎提供任何提示。

+0

你试过了吗? GNU支持你想要的语法。 –

+0

我用另一个替换了kludge,无条件链接所有输入作为变量初始化的一部分。这似乎工作,并不再使用-j时挂起。 LINKTMPFILES:= $(壳MKDIR -p TMP /; RM TMP/*; LN -fs $(输入)TMP /) : %的.out:%的.txt 一些命令 还没成为优雅的典范,但是...... ***对不起,我没有被允许作为一个单独的答案发布它*** – Ketil

+0

@JoachimPileborg:呃,你可能会更具体吗? – Ketil

回答

0

你想要这样的东西吗?

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

.PHONY: default 
default: $(TARGET) 

$(TARGET): $(OUTPUT) 
    cat $^ > [email protected] 

%.out: %.txt 
    cp $< [email protected] 

试图与-j选项make,但对于这样一个简单的例子可以很容易地解决依赖性和构建并行。

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> 
+0

在你的例子中的问题是,输入(txt)文件驻留在当前目录中,而我想从任意位置导入它们。我知道patsubst等人,但我不知道如何做到这一点(即从变量列表中选择一个项目)。 – Ketil

+0

这没有问题。你的输入文件可以在任何地方。它会创建与完整源路径匹配的目录“out”以外的子目录。 –

0

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

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

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

merged.txt: $(OUTPUTS) 
    <merge command> $^ -o [email protected] 

%.out: %.txt 
    <some command> $< -o [email protected] 

该解决方案依赖于有没有被重复的文件名,但我认为你通过创建符号链接暗示条件。

+0

我不知道VPATH,看起来它可能是我想要的,是的。谢谢! – Ketil