为项目子目录中的目标创建依赖关系的make规则

前端之家收集整理的这篇文章主要介绍了为项目子目录中的目标创建依赖关系的make规则前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的论文研究软件的源代码树(R)反映了传统的研究工作流程:“收集数据 – >准备数据 – >分析数据 – >收集结果 – >发布结果”.我使用make来建立和维护工作流(项目的大多数子目录都包含Makefile文件).

但是,我经常需要通过项目子目录中的特定Makefile目标(而不是通过顶级Makefile)执行工作流的各个部分.这会产生一个问题,即设置Makefile规则以维护来自工作流的不同部分的目标之间的依赖关系,换句话说 – 在Makefile文件中的目标之间,位于不同的子目录中.

以下代表我的论文项目的设置:

+-- diss-floss (Project's root)
|-- import (data collection)
|-- cache (R data objects (),representing different data sources,in sub-directories)
|-+ prepare (data cleaning,transformation,merging and sampling)
  |-- R modules,including 'transform.R'
|-- analysis (data analyses,including exploratory data analysis (EDA))
  |-- R modules,including 'eda.R'
|-+ results (results of the analyses,in sub-directories)
  |-+ eda (*.svg,*.pdf,...)
  |-- ...
|-- present (auto-generated presentation for defense)

我的一些Makefile文件中的目标片段:

“〜/ diss-floss / Makefile”(几乎已满):

# Major variable definitions

PROJECT="diss-floss"
HOME_DIR="~/diss-floss"
REPORT={$(PROJECT)-slides}

COLLECTION_DIR=import
PREPARATION_DIR=prepare
ANALYSIS_DIR=analysis
RESULTS_DIR=results
PRESENTATION_DIR=present

RSCRIPT=Rscript

# Targets and rules 

all: rprofile collection preparation analysis results presentation

rprofile:
    R CMD BATCH ./.Rprofile

collection:
    cd $(COLLECTION_DIR) && $(MAKE)

preparation: collection
    cd $(PREPARATION_DIR) && $(MAKE)

analysis: preparation
    cd $(ANALYSIS_DIR) && $(MAKE)

results: analysis
    cd $(RESULTS_DIR) && $(MAKE)

presentation: results
    cd $(PRESENTATION_DIR) && $(MAKE)


## Phony targets and rules (for commands that do not produce files)

#.html
.PHONY: demo clean

# run demo presentation slides
demo: presentation
    # knitr(Markdown) => HTML page
    # HTML5 presentation via RStudio/RPubs or Slidify
    # OR
    # Shiny app

# remove intermediate files
clean:
    rm -f tmp*.bz2 *.Rdata

“〜/迪斯 – 牙线/进口/ Makefile文件”:

importFLOSSmole: getFLOSSmoledataxML.R
    @$(RSCRIPT) $(R_OPTS) $<
...

“〜/ DISS-牙线/准备/生成文件”:

transform: transform.R
    $(RSCRIPT) $(R_OPTS) $<
...

“〜/迪斯 – 牙线/分析/ Makefile文件”:

eda: eda.R
    @$(RSCRIPT) $(R_OPTS) $<

目前,我担心创建以下依赖项:

通过在导入中从Makefile制作目标而收集的数据总是需要通过在准备之前使Makefile中的相应目标进行转换,例如eda.R.如果我在导入时手动运行make然后忘记转换,请在分析中运行make eda,事情进展不顺利.因此,我的问题是:

我怎样才能使用make实用程序的功能(以最简单的方式)来建立和维护不同目录中Makefile文件中目标之间依赖关系的规则?

您现在使用makefile的问题是您只将代码列为依赖项,而不是数据.这就是很多魔术发生的地方.如果“分析”知道它将使用哪些文件并且可以将它们列为依赖项,那么它可以回顾它们是如何制作的以及它们具有哪些依赖关系.如果管道中的早期文件已更新,那么它可以运行所有必要的步骤以使文件保持最新.例如
import: rawdata.csv

rawdata.csv:
    scp remoteserver:/rawdata.csv .

transform: tansdata.csv

transdata.csv: gogo.pl rawdata.csv
    perl gogo.pl $< > $@

plot: plot.png

plot.png: plot.R transdata.csv
    Rscript plot.R

因此,如果我进行make导入,它将下载一个新的csv文件.然后,如果我运行make plot,它将尝试make plot.png但这取决于transdata.csv并且这取决于rawdata.csv并且因为rawdata.csv已更新,所以它需要更新transdata.csv然后它将准备好运行R脚本.如果你没有明确设置很多文件依赖项,那么你就错过了很多make的强大功能.但是要失败,有时候在那里获得所有正确的依赖关系会很棘手(特别是如果你从一个步骤产生多个输出).

猜你在找的设计模式相关文章