【问题标题】:combine files for makefile lead to make No targets为 makefile 组合文件导致没有目标
【发布时间】:2015-10-19 10:48:39
【问题描述】:

我有以下文件和目录结构,其中包含很多文件和目录:

$ tree
input/
├── C-1-28558666
│   ├── MGRF-C1_S10_L001_R1_001.fastq.gz
│   ├── MGRF-C1_S10_L001_R2_001.fastq.gz
│   ├── MGRF-C1_S10_L002_R1_001.fastq.gz
│   ├── MGRF-C1_S10_L002_R2_001.fastq.gz
│   ├── MGRF-C1_S10_L003_R1_001.fastq.gz
│   ├── MGRF-C1_S10_L003_R2_001.fastq.gz
│   ├── MGRF-C1_S10_L004_R1_001.fastq.gz
│   └── MGRF-C1_S10_L004_R2_001.fastq.gz
├── C-2-28577664
│   ├── MGRF-C2_S11_L001_R1_001.fastq.gz
│   ├── MGRF-C2_S11_L001_R2_001.fastq.gz
│   ├── MGRF-C2_S11_L002_R1_001.fastq.gz
│   ├── MGRF-C2_S11_L002_R2_001.fastq.gz
│   ├── MGRF-C2_S11_L003_R1_001.fastq.gz
│   ├── MGRF-C2_S11_L003_R2_001.fastq.gz
│   ├── MGRF-C2_S11_L004_R1_001.fastq.gz
│   └── MGRF-C2_S11_L004_R2_001.fastq.gz 
...

每个文件名都包含 R1 或 R2。具有 R1 和 R2 的文件属于一起,下面的命令使用这两个文件和一个 dm6.fasta.bwt 文件。

bwa mem ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb - > BAMs/C-1-28558666/MGRF-C1_S10_L001.bam

我已尝试编写以下 Makefile 规则:

BAMs/%.bam: $(addsuffix .bwt,${REFERENCE}) $(foreach SIDE,R1 R2, ../MGRF_NGS_KUMARAN-25071046/*/*${SIDE}*.fq.gz )
    bwa mem ${REFERENCE} $(filter %.fq.gz,$^) | samtools view -Sb - > @>

但是,我得到了:

$ make -n 
make: *** No targets.  Stop.

如何修复上面的 Makefile?

【问题讨论】:

  • 如果这是您的整个 makefile,那么您的问题是您没有告诉 make 实际构建任何文件。您刚刚给它一个模式来匹配目标文件名。话虽这么说,makefile 目标/等。根本不会做你想做的事。
  • 我刚从第一条规则开始。我如何告诉上面的例子来构建文件?
  • 您实际上需要告诉 make 构建目标:例如 make BAMs/file.bam 或在您的 makefile 中有一个类似 all: BAMs/file.bam BAMs/otherfile.bam ... 的目标,因此 make 有一个默认值。但是就像我说的那样,您的目标规则存在 host 的其他问题。
  • 您在规则中使用未经修改的${REFERENCE}(而不是.bwt 后缀版本)。 每个 BAMs/%.bam 文件将依赖于每个 通配的R1R2 文件(不仅仅是与输出文件名匹配的文件)。您在 samtools 命令上有一个尾随 >。您的目录列表显示.fastq.gz,但您的makefile 使用.fq.gz(我不知道哪个是正确的)。
  • 谢谢,下面的 Renaud 重写了我的 Makefile,但目前无法处理 R1R2

标签: makefile gnu-make


【解决方案1】:

您的第一个问题来自这样一个事实,即如果没有明确请求模式规则,它们就不会创建目标。因此,您需要明确列出要制作的目标。在以下示例中,它们列在BAMS make 变量中,然后用作all 目标的依赖项,这是makefile 的第一个目标。因此all 是默认目标,输入makemake all 将构建所有bams

您的第二个问题是处理每个bam 目标的R1R2 依赖项对。 GNU make static 模式规则在这种情况下非常有用:

REFERENCE := ref/dm6.fasta
DIRS := $(wildcard input/*)
R1S  := $(foreach dir,$(DIRS),$(wildcard $(dir)/*_R1_001.fastq.gz))
RR1S := $(patsubst input/%_R1_001.fastq.gz,%,$(R1S))
BAMS := $(patsubst %,BAMs/%.bam,$(RR1S))

all: $(BAMS)

$(BAMS): BAMs/%.bam: $(REFERENCE).bwt input/%_R1_001.fastq.gz input/%_R2_001.fastq.gz
    @mkdir -p $(dir $@); \
    bwa mem $^ | samtools view -Sb - > $@

target: target-pattern: prerequisite-pattern 是静态模式规则。

GNU make 还有几个函数(callevalforeach)可用于更复杂的示例:

REFERENCE := ref/dm6.fasta
DIRS := $(wildcard input/*)
R1S  := $(foreach dir,$(DIRS),$(wildcard $(dir)/*_R1_001.fastq.gz))
RR1S := $(patsubst input/%_R1_001.fastq.gz,%,$(R1S))
BAMS := $(patsubst %,BAMs/%.bam,$(RR1S))

all: $(BAMS)

define BAM_rule
BAMs/$(1).bam: $(REFERENCE).bwt input/$(1)_R1_001.fastq.gz input/$(1)_R2_001.fastq.gz
    @mkdir -p $$(dir $$@); \
    bwa mem $$^ | samtools view -Sb - > $$@
endef

$(foreach r,$(RR1S),$(eval $(call BAM_rule,$(r))))

说明:

RR1S 变量列出了所有 C-1-28558666/MGRF-C1_S10_L001 词干。然后使用它来构建列出目标的BAMS 变量。 BAM_rule 变量是从其对应的 R1R2 依赖项构建 bam 目标的规则框架。 $(1) 是使用call 函数时将被扩展的参数:$(call BAM_rule,foo) 扩展BAM_rule 并将所有出现的$(1) 替换为foo。请注意,某些$ 符号必须加倍才能被第一次扩展保留。最后,

$(foreach r,$(RR1S),$(eval $(call BAM_rule,$(r))))

遍历所有词干并使用eval 函数为每个词干实例化一个BAM_rule,由call 扩展和专门化。

然后,正常的 make 扩展会将 BAM_rule 的每个实例转换为您将为给定目标手动编写的规则:

BAMs/C-1-28558666/MGRF-C1_S10_L001.bam: ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz
    @mkdir -p BAMs/C-1-28558666; \
    bwa mem ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb - > BAMs/C-1-28558666/MGRF-C1_S10_L001.bam

【讨论】:

  • 谢谢,但我无法弄清楚 2 个 FASTQ(R1R2)文件如何生成 1 个 BAM 文件,例如input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb - > BAMs/C-1-28558666/MGRF-C1_S10_L001.bam?
  • _001.fastq.gz 是常量还是_002.fastq.gz...?
  • 是的,_001.fastq.gz 是常数,没有_002.fastq.gz
  • 我更新了我的答案,向您展示如何使用静态模式规则或foreach-eval-call 来处理您的 R1 和 R2 依赖项。
猜你喜欢
  • 2015-02-13
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
相关资源
最近更新 更多