0

这是我的 Makefile 中的两个目标。

.SECONDARY: 
exp-%.ans: 
    echo $* > eval/$@

%.scores: %.ans
    cat eval/$< > eval/$@

当我写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/$@

%.scores: eval/%.ans
    cat eval/$< > $@

当我再次写入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。我还想检查文件是否已经存在。然后 make 应该根据该文件的存在进行。

谢谢。

4

1 回答 1

2

make 的核心规则之一是您需要构建您的规则告诉您要构建的目标。像这样的规则foo : bar告诉 make 如果它运行该配方,该配方将创建或更新一个名为foo. 如果配方创建或更新了一个名为的文件biz/foo,那么你的 makefile 是错误的,事情将无法正常工作。

Make 总是将它期望配方创建的目标放入$@自动变量中。您的食谱应该创建或更新$@并且完全正确$@。不是别的。

所以在你的情况下,你需要写:

eval/exp-%.ans: 
        echo $* > $@

eval/%.scores: eval/%.ans
        cat $< > $@

如果您希望能够运行make exp-40.scores并让它实际创建eval/exp-40.scores,那么您可以添加这样的规则:

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

(你必须为模式规则提供某种配方,它们不能有一个空的配方;上面的那个什么都不做)。

于 2013-07-24T15:57:11.910 回答