Дерево исходного кода (R
) для моего программного обеспечения для исследований исследований отражает традиционный рабочий процесс исследований: "собирать данные → готовить данные → анализировать данные → собирать результаты → публиковать результаты". Я использую make
для создания и поддержания рабочего процесса (большинство подкаталогов проекта содержат файлы Makefile
).
Однако часто мне нужно выполнять отдельные части моего рабочего процесса через определенные цели Makefile в подкаталогах проекта (а не через верхний уровень Makefile
). Это создает проблему настройки Makefile
правил для поддержки зависимостей между целями из разных частей рабочего процесса, другими словами - между целями в файлах Makefile
, расположенных в разных подкаталогах.
Ниже представлен setup для моего проекта диссертации:
+-- diss-floss (Project 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) $<
...
"~/дисс-зубочистка/подготовки/Makefile":
transform: transform.R
$(RSCRIPT) $(R_OPTS) $<
...
"~/дисс-нить/анализ/Makefile":
eda: eda.R
@$(RSCRIPT) $(R_OPTS) $<
В настоящее время меня беспокоит создание следующей зависимости:
Данные, собранные путем создания цели из Makefile
в import
, всегда должны быть преобразованы путем создания соответствующей цели из Makefile
в prepare
перед анализом через, например, eda.R
. Если я вручную запустил make
в import
, а затем, забыв о преобразовании, запустите make eda
в analyze
, все идет не слишком хорошо. Поэтому мой вопрос:
Как я могу использовать функции утилиты make
(самым простым способом) для установления и поддержания правил зависимостей между целями из Makefile
файлов в разных каталогах?