2013-07-24 126 views
0

这是我的Makefile中的两个目标。Makefile中的路径依赖关系

.SECONDARY: 
exp-%.ans: 
    echo $* > eval/[email protected] 

%.scores: %.ans 
    cat eval/$< > eval/[email protected] 

当我写make -n exp-40.scores输出为:

echo 40 > eval/exp-40.ans 
cat eval/exp-40.ans > eval/exp-40.scores 

这是很好的,除了一两件事。它不知道依赖已经被保留。如果我创建eval/exp-40.scores(第一次),那么我希望make会说它已经在那里,如果我运行相同的命令。所以,我试图改变我的Makefile是这样的:

.SECONDARY: 
exp-%.ans: 
    echo $* > eval/[email protected] 

%.scores: eval/%.ans 
    cat eval/$< > [email protected] 

当我再次写make -n exp-40.scores输出将是:

echo eval/40 > eval/eval/exp-40.ans 
cat eval/eval/exp-40.ans > exp-40.scores 

这是完全错误的,因为我的参数应该是40不EVAL/40。

我该如何实现这两个世界中最好的?也就是说,我想在eval /文件夹中创建* .scores。我也想做检查文件是否已经存在或没有。然后使该按照该文件存在进行。

谢谢。

回答

2

make的核心规则之一就是你需要建立你的规则告诉你的目标。像foo : bar这样的规则告诉如果它运行该配方,配方将创建或更新名为foo的文件。如果配方创建或更新一个名为biz/foo的文件,那么您的makefile是错误的,并且不起作用。

Make始终将它希望创建的配方放入[email protected]自动变量中。你的配方应该创建或更新[email protected][email protected]。不是别的。

你的情况

所以,你需要写:

eval/exp-%.ans: 
     echo $* > [email protected] 

eval/%.scores: eval/%.ans 
     cat $< > [email protected] 

如果你想能够运行make exp-40.scores并有它实际上创造eval/exp-40.scores,那么你就可以添加一条规则是这样的:

%.scores: eval/%.scores ; @: 

(你必须提供一些模式规则的配方,他们不能有一个空的配方;上面的一个没有做什么)。

+0

非常感谢您在开始时的回答和澄清。我需要一个包含Makefile性质的教程。你知道这件事吗?网上有很多简短的教程,其目的通常是提供一些技巧和窍门来做快速和肮脏的事情。我听说(我不确定)make的文档不好,存在很多bug。有一本O'Reilly的书(http://shop.oreilly.com/product/9780596006105.do),但它的评价是平均的。 – Thorn

+0

如果你不好意思,我想再问两个问题。 (1)如果我删除.SECONDARY,则删除我的中间文件,这对我来说非常重要。我阅读(章节为.SECONDARY,.INTERMEDIATE和.PRECIOUS)手册,但我不明白哪一个适合这种情况。 (2)并且.SECONDARY是否会影响下面的所有目标? – Thorn

+2

我认为GNU make手册不错。我不知道它有任何错误。但是请注意,GNU网站上的手册版本记录了GNU make的最新稳定版本。如果您使用的是旧版本,那么手册中的某些语句将不适合您的版本。您应该阅读与您使用的GNU版本相同的手册版本,以避免混淆。本手册与GNU make一起打包,因此您应该能够从您制作软件包的相同位置为您的版本获取正确的文档。 – MadScientist