推迟变量分配,直到文件存在或在 Makefile 中执行规则

Posted

技术标签:

【中文标题】推迟变量分配,直到文件存在或在 Makefile 中执行规则【英文标题】:Defer variable assignment until file present or rule executed in Makefile 【发布时间】:2015-08-26 13:14:13 【问题描述】:

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

# 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 > $@

【问题讨论】:

您没有在该 sn-p 中启用二级扩展。您也不要在任何地方使用download 目标。您能否提供一个完整且准确的生成文件来代表您的尝试之一。话虽如此,在处理了先决条件之前,您将无法了解无法确定的目标。你必须以另一种方式工作。您需要获取 prereq,然后您可以从中确定依赖它的目标(生成的包含的 makefile 在这里可能很有用)。 @EtanReisner 抱歉,我添加了二次扩展。下载目标是 makefile 中的第一个目标,因此默认情况下它会在我运行 make 时执行。 【参考方案1】:

要做你想做的事,你想要更多这样的东西(cmets inline):

# 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。

【讨论】:

以上是关于推迟变量分配,直到文件存在或在 Makefile 中执行规则的主要内容,如果未能解决你的问题,请参考以下文章

C/C++经典面试题(转载)

长文预警!C语言与C++常见问答题

C++面试八股文快问快答の基础篇

Ruby 分配一个变量或在 nil 时引发错误

如何将命令的输出分配给 Makefile 变量

[Linux 高并发服务器]Makefile