在项目的子目录中为跨目标的依赖关系创建 make 规则 [英] Creating make rules for dependencies across targets in project's sub-directories
问题描述
我的论文研究软件的源代码树(R
)反映了传统的研究工作流程:收集数据 -> 准备数据 -> 分析数据 -> 收集结果 ->公布结果".我使用make
来建立和维护工作流(项目的大部分子目录都包含Makefile
文件).
Source code tree (R
) for my dissertation research software reflects traditional research workflow: "collect data -> prepare data -> analyze data -> collect results -> publish results". I use make
to establish and maintain the workflow (most of the project's sub-directories contain Makefile
files).
但是,我经常需要通过项目子目录中的特定 Makefile 目标(而不是通过顶级 Makefile
)来执行工作流的各个部分.这会产生一个问题,即设置 Makefile
rules 以维护来自工作流不同部分的目标之间的 dependencies,换句话说 - 中的目标之间code>Makefile 文件,位于不同的子目录中.
However, frequently, I need to execute individual parts of my workflow via particular Makefile targets in project's sub-directories (not via top-level Makefile
). This creates a problem of setting up Makefile
rules to maintain dependencies between targets from different parts of the workflow, in other words - between targets in Makefile
files, located in different sub-directories.
以下代表我的论文项目的设置:
The following represents the setup for my dissertation project:
+-- 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
文件中的目标片段:
Snippets of targets from some of my Makefile
files:
~/diss-floss/Makefile"(快满了):
"~/diss-floss/Makefile" (almost full):
# 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
~/diss-floss/import/Makefile":
"~/diss-floss/import/Makefile":
importFLOSSmole: getFLOSSmoleDataXML.R
@$(RSCRIPT) $(R_OPTS) $<
...
~/diss-floss/prepare/Makefile":
"~/diss-floss/prepare/Makefile":
transform: transform.R
$(RSCRIPT) $(R_OPTS) $<
...
~/diss-floss/analysis/Makefile":
"~/diss-floss/analysis/Makefile":
eda: eda.R
@$(RSCRIPT) $(R_OPTS) $<
目前,我担心创建以下依赖项:
Currently, I am concerned about creating the following dependency:
数据,通过import
中的Makefile
制作目标收集,总是需要通过Makefile
制作对应目标进行转换>prepare 在通过例如 eda.R
进行分析之前.如果我在 import
中手动运行 make
,然后忘记转换,在 analyze
中运行 make eda
,事情就是这样不太顺利.因此,我的问题是:
Data, collected by making a target from Makefile
in import
, always needs to be transformed by making corresponding target from Makefile
in prepare
before being analyzed via, for example eda.R
. If I manually run make
in import
and then, forgetting about transformation, run make eda
in analyze
, things are not going too well. Therefore, my question is:
我如何使用 make
实用程序的功能(以最简单的方式)来建立和维护来自 Makefile
文件的不同目标之间的依赖关系规则目录?
How could I use features of the make
utility (in a simplest way possible) to establish and maintain rules for dependencies between targets from Makefile
files in different directories?
推荐答案
以下是我对将我的研究工作流程的数据依赖项添加到项目当前的 make
基础设施(带有代码片段).我还尝试通过在 make
targets 之间指定 dependencies 来反映所需的工作流程.
The following are my thoughts (with some ideas from @MrFlick's answer - thank you) on adding my research workflow's data dependencies to the project's current make
infrastructure (with snippets of code). I have also tried to reflect the desired workflow by specifying dependencies between make
targets.
导入/生成文件:
importFLOSSmole: getFLOSSmoleDataXML.R FLOSSmole.RData
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
(similar targets for other data sources)
准备/生成文件:
IMPORT_DIR=../import
prepare: import
transform
cleanup
merge
sample
import: $IMPORT_DIR/importFLOSSmole.done # and/or other flag files, as needed
transform: transform.R import
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
cleanup: cleanup.R transform
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
merge: merge.R cleanup
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
sample: sample.R merge
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
分析/Makefile:
PREP_DIR=../prepare
analysis: prepare
eda
efa
cfa
sem
prepare: $PREP_DIR/transform.done # and/or other flag files, as needed
eda: eda.R prepare
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
efa: efa.R eda
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
cfa: cfa.R efa
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
sem: sem.R cfa
@$(RSCRIPT) $(R_OPTS) $<
@touch $@.done
results
和 present
目录下的 Makefile
文件内容仍待定.
The contents of Makefile
files in directories results
and present
are still TBD.
感谢您对上述内容的想法和建议!
这篇关于在项目的子目录中为跨目标的依赖关系创建 make 规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!