makefile:从3输入生成一个输出

时间:2017-05-24 16:14:45

标签: makefile gnu-make

我有这个版本的makefile [sbsuser@compute-00-01 415]$ make --version GNU Make 3.81

我有目录SOMATIC,其中有3个文件。我想生产一个只有一个输出。这就是我写的。

`

OUTSOMATIC=SOMATIC
FINAL=FINAL
INPUT=$(wildcard $(OUTSOMATIC)/*.vcf)
OUTSORT2= $(patsubst $(OUTSOMATIC)/%.vcf,$(FINAL)/%somatic.ensemble.gz,$(INPUT))
$(info lista $(OUTSORT2))
$(info lista $(INPUT))
.PHONY: all
all: $(INPUT) $(OUTSOMATIC) $(OUTSORT2) $(FINAL)
$(FINAL)/%somatic.ensemble.gz: $(OUTSOMATIC)/%.vcf $(INPUT)
    ~/jdk1.8.0_121/bin/java -XX:+UseSerialGC -Xms1g -Xmx10g -jar /illumina/software/PROG2/bcbio-variation-recall-0.1.7  ensemble  -n 1 $(FINAL)/somatic_ensemble.gz /illumina/software/database/database_2016/hg19_primary.fa $^

`

用这个脚本制作3次相同的文件。我不明白如何只在同一时间使用的输入列表中创建一个输出。 做这个的最好方式是什么? 如果我更改了$(FINAL)/%somatic.ensemble.gz$(FINAL)/somatic.ensemble.gz我有这个错误:

make: *** No rule to make target FINAL/415_merge_mutect2.somaticsomatic.ensemble.gz', needed by全部&#39 ;. Stop`

1 个答案:

答案 0 :(得分:2)

您可能应该查看GNU制作手册介绍部分,其中介绍了如何使用。

让我们来看看你的makefile;首先定义一些变量。假设您有文件SOMATIC/foo.vcfSOMATIC/bar.vcfSOMATIC/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

现在,make看到您已定义了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

因此,make将尝试构建all目标的每个先决条件,以确保它是最新的。首先,它尝试构建SOMATIC/*.vcf文件。这些文件已经存在,make没有关于如何重建它们的任何规则,所以它假定它们是最新的。

接下来,它尝试构建SOMATIC文件。这是一个目录,它也没有要构建的规则,因此make假设它也是最新的。

接下来尝试构建目标FINAL/foosomatic.ensemble.gz。让确实有一个可以构建它的规则,你创建了一个:

$(FINAL)/%somatic.ensemble.gz: $(OUTSOMATIC)/%.vcf $(INPUT)
        ~/jdk1.8.0_121/bin/java ...

这与您要构建的目标匹配,%值为foo,因此请在%的先决条件中替换foo并找到{ {1}}存在并且不需要重建,因此它会运行您的食谱。但是,您的食谱实际上并未创建目标SOMATIC/foo.vcf;它会创建目标FINAL/foosomatic.ensemble.gz。所以这个规则被打破了,因为它告诉它会做一件事,但它做了别的事情。

您应该始终确保所有食谱都构建自动变量FINAL/somatic_ensemble.gz所代表的文件;这将确保您并就您的规则的含义达成一致。如果您希望您的配方构建其他文件,那么您的规则写得不正确。

下一步使用$@all的下一个先决条件做同样的事情。由于该文件不存在,因此尝试使用模式规则构建它,但同样会创建相同的输出文件。

再次为第三个.gz文件FINAL/barsomatic.ensemble.gz。这就是事情运行三次的原因。

如果您将模式规则更改为显式规则构建FINAL/bazsomatic.ensemble.gz,这是您想要的,那么make无法找到任何方法来构建FINAL/somatic.ensemble.gz目标的先决条件,因此它给出了这个错误。

您的问题是all的创建。您只想创建一个输出文件,但是您已将OUTSORT2设置为包含三个不同的文件,因此请尝试创建所有三个文件。你想要这个:

OUTSORT2