您可能應該查看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 $^
非常感謝! –