如何获取makefile来运行所有命令,无论目标或依赖项如何

时间:2014-10-17 12:01:11

标签: makefile bioinformatics fastq

我正在编写一个GNUmakefile来创建一个工作流来分析一些生物序列数据。数据采用称为fastq的格式,然后经过许多清理和分析工具。我已经附上了我目前所写的内容,这使我在清洁之前从质量控制开始,然后是质量控制。我的问题是我不确定如何运行'fastqc'命令,因为它的目标不是工作流中任何其他步骤的依赖。

 %_sts_fastqc.html %_sts_fastqc.zip: %_sts.fastq
    # perform quality control after cleaning reads
    fastqc $^

%_sts.fastq: %_st.fastq
    # trim reads based on quality
    sickle se -f $^ -t illumina -o $@

%_st.fastq: %_s.fastq
    # remove contaminated reads
    tagdust -s adapters.fa $^

%_s.fastq: %.fastq
    # trim adapters
    scythe -a <adapters.fa> -o $@ $^

%_fastqc.html %_fastqc.zip: %.fastq
    # perform quality control before cleaning reads
    fastqc $^

%.fastq: %.sra
    # convert .fastq to .sra
    fastq-dump $^

2 个答案:

答案 0 :(得分:1)

我相信将这些行添加到Makefile的开头可以满足您的要求:

SOURCES:=$(wildcard *.sra)
TARGETS:=$(SOURCES:.sra=_fastqc.html) $(SOURCES:.sra=_fastqc.zip)\
     $(SOURCES:.sra=_sts_fastqc.html) $(SOURCES:.sra=_sts_fastqc.zip)

.PHONY: all
all: $(TARGETS)

这样做是从文件系统中获取所有.sra文件,并通过用生成目标所需的任何字符串替换扩展来构建要构建的目标列表。 (注意htmlzip目标是由同一个命令产生的,我可以拥有一个或另一个,但是我决定放两个,以防规则发生变化,{{1 }}和hmtl目标是单独生成的。)然后它设置假的zip目标来构建所有计算目标。这是一个Makefile我已经通过在任何地方添加all来修改你的,我用来检查一切正常,而不必在Makefile中运行实际的命令。您可以将其复制并粘贴到文件中,首先检查一切正常,然后再使用上面的行修改自己的Makefile。这是:

@echo

我在此处通过运行SOURCES:=$(wildcard *.sra) TARGETS:=$(SOURCES:.sra=_fastqc.html) $(SOURCES:.sra=_fastqc.zip)\ $(SOURCES:.sra=_sts_fastqc.html) $(SOURCES:.sra=_sts_fastqc.zip) .PHONY: all all: $(TARGETS) %_sts_fastqc.html %_sts_fastqc.zip: %_sts.fastq # perform quality control after cleaning reads @echo fastqc $^ %_sts.fastq: %_st.fastq # trim reads based on quality @echo sickle se -f $^ -t illumina -o $@ %_st.fastq: %_s.fastq # remove contaminated reads @echo tagdust -s adapters.fa $^ %_s.fastq: %.fastq # trim adapters @echo 'scythe -a <adapters.fa> -o $@ $^' %_fastqc.html %_fastqc.zip: %.fastq # perform quality control before cleaning reads @echo fastqc $^ %.fastq: %.sra # convert .fastq to .sra @echo fastq-dump $^ 然后运行touch a.sra b.sra对其进行了测试。它运行了两个文件的命令。

答案 1 :(得分:0)

而不是使用模式,我会使用'define':

 # 'all' is not a file 
.PHONY: all 
# a list of 4 samples
SAMPLES=S1 S2 S3 S4

#define a macro named analyzefastq. It takes one argument $(1). we need to protect the '$' for later expension using $(eval)
define analyzefastq 
# create a .st.fastq from fastq for file $(1)
$(1).st.fastq  : $(1).fastq
    tagdust -s adapters.fa $$^
# create a .fastq from seq for file $(1)
$(1).fastq : $(1).sra
    fastq-dump $$^

endef

#all : final target  dependency is all samples with a suffix '.st.fastq'
all: $(addsuffix ${S}.st.fastq, ${SAMPLES} )

## loop over each sample , name of variable is 'S' call and eval the previous macro, using 'S'=sample for the argument
$(foreach S,${SAMPLES},$(eval $(call analyzefastq,$(S))) )

我还使用我的工具jsvelocity https://github.com/lindenb/jsvelocity为NGS生成大型Makefile:

https://gist.github.com/lindenb/3c07ca722f793cc5dd60