您可能应该查看GNU make手册介绍部分,在这些章节中他们描述了工作原理。我们来看看你的makefile;首先你定义一些变量。假设您有文件SOMATIC/foo.vcf
,SOMATIC/bar.vcf
和SOMATIC/baz.vcf
。然后,你创建的变量将是这些值,他们是扩大后:
OUTSOMATIC = SOMATIC
FINAL = FINAL
INPUT = SOMATIC/foo.vcf SOMATIC/bar.vcf SOMATIC/baz.vcf
现在你patsubst
发现在INPUT
匹配模式SOMATIC/%.vcf
并更换与FINAL/%somatic.ensemble.gz
,其中一部分在该%
匹配所有单词输入代入输出:
OUTSORT2 = FINAL/foosomatic.ensemble.gz FINAL/barsomatic.ensemble.gz FINAL/bazsomatic.ensemble.gz
现在,让我们看看您已经定义了一个all
目标。由于它是makefile中的第一个目标,因此这是默认运行的目标。扩建后,它看起来就像这样:
all: SOMATIC/foo.vcf SOMATIC/bar.vcf SOMATIC/baz.vcf SOMATIC FINAL/foosomatic.ensemble.gz FINAL/barsomatic.ensemble.gz FINAL/bazsomatic.ensemble.gz FINAL
因此,请将尝试建立all
目标的每一个先决条件,以确保它是最新的。首先它试图构建SOMATIC/*.vcf
文件。这些文件已经存在,并且没有关于如何重建它们的任何规则,所以它假定它们是最新的。
接下来它尝试构建SOMATIC
文件。这是一个目录,它也没有规则要建立,所以假设这是最新的。
下一步make尝试构建目标FINAL/foosomatic.ensemble.gz
。让不有可以建造它的规则,你已经创建了一个:
$(FINAL)/%somatic.ensemble.gz: $(OUTSOMATIC)/%.vcf $(INPUT)
~/jdk1.8.0_121/bin/java ...
这符合你想建立的目标,与foo
一个%
值,所以后来做出的前提代替了%
对于foo
,发现SOMATIC/foo.vcf
存在并且不需要重建,因此它会运行您的配方。然而你的食谱实际上并不创造目标FINAL/foosomatic.ensemble.gz
;它会创建目标FINAL/somatic_ensemble.gz
。所以这个规则被破坏了,因为它告诉它会做一件事,但它做了其他事情。
您应该始终确保所有食谱都生成由自动变量[email protected]
表示的文件;这将确保你和你的规则的含义达成一致。如果你想让你的食谱建立一些其他文件,那么你的规则写错了。
下一步使用下一个先决条件all
做同样的事情:FINAL/barsomatic.ensemble.gz
。由于该文件不存在,make会尝试使用模式规则来构建它,但同样会创建相同的输出文件。
再次为第三个.gz文件FINAL/bazsomatic.ensemble.gz
。这就是为什么事情运行三次。
如果将模式规则更改为明确的规则构建FINAL/somatic.ensemble.gz
,这是您想要的,然后使无法找到任何方式来构建all
目标的先决条件,因此它会给出此错误。您的问题是创建OUTSORT2
。您只想创建一个输出文件,但您已将OUTSORT2
设置为包含三个不同的文件,因此make会尝试创建所有三个文件。你想要这个:
OUTSOMATIC = SOMATIC
FINAL = FINAL
INPUT = $(wildcard $(OUTSOMATIC)/*.vcf)
OUTSORT2 = $(FINAL)/somatic.ensemble.gz
.PHONY: all
all: $(OUTSORT2)
$(OUTSORT2): $(INPUT)
~/jdk1.8.0_121/bin/java -XX:+UseSerialGC -Xms1g -Xmx10g -jar /illumina/software/PROG2/bcbio-variation-recall-0.1.7 ensemble -n 1 [email protected] /illumina/software/database/database_2016/hg19_primary.fa $^
非常感谢! –