延迟变量赋值,直到文件存在或在 Makefile 中执行规则

Defer variable assignment until file present or rule executed in Makefile

我有一个从生物数据库下载数据的 Makefile。给定一个项目编号,它应该首先下载一个包含该项目所有 运行 信息的文件,然后从信息中提取登录号,然后并行下载与这些登录号相关联的 FASTQ 文件。我的问题是我无法将变量 FASTQ 推迟到下载 run.txt 和 sra.txt 之后。我尝试了仅订单先决条件和 .SECONDEXPANSION 的组合,但仍然无法使其工作。有可能吗?

# Project
PROJECT := PRJNA257197

# Download
.SECONDEXPANSION:
FASTQ = $(patsubst %, %.fastq, $(shell cat sra.txt))
download: $$(FASTQ) | run.txt sra.txt

%.fastq: sra.txt
    # Download FASTQ files
    fastq-dump $*

sra.txt: run.txt
    # Extract SRA accession numbers
    cat $^ | cut -f 1 -d ',' | grep SRR | tr '\n' ' ' > $@ 

run.txt:
    # Download run information
    esearch -db sra -query $(PROJECT) | efetch -format runinfo > $@

做你想做的事你想要更像这样的东西(内嵌评论):

# Project
PROJECT := PRJNA257197

# Include the fastqs.mk makefile.
include fastqs.mk

# Default target is all the fastq files.
all: $(FASTQS)

%.fastq: sra.txt
    # Download FASTQ files
    fastq-dump $*

# Create the fastqs.mk file from sra.txt.
fastqs.mk: sra.txt
    sed 's.*/FASTQS+=&.fastq/' $< > $@

sra.txt: run.txt
    # Extract SRA accession numbers
    cat $^ | cut -f 1 -d ',' | grep SRR | tr '\n' ' ' > $@ 

run.txt:
    # Download run information
    esearch -db sra -query $(PROJECT) | efetch -format runinfo > $@

假设每个 .fastq 文件都有一个匹配的裸文件(即 foo.fastq -> foo),那么您可能希望将其作为模式目标。

%.fastq: % sra.txt

这里的魔力在于包含的 makefile。具体来说,make 足够聪明,可以注意到何时需要构建包含的 makefile 并在完成后重新启动处理。有关详细信息,请参阅手册中的 How Makefiles Are Remade