【问题标题】:Remove duplication in a Makefile: Target files are written once under Phony variable `all` and again as recipe targets删除 Makefile 中的重复:目标文件在 Phony 变量 `all` 下写入一次,然后再次作为配方目标
【发布时间】:2020-02-08 05:07:37
【问题描述】:

下面我复制了一个 Makefile 示例,用于执行一些脚本来清理和合并数据。

这种 Makefile 格式要求我列出每个目标文件两次:一次在 all 下,一次作为每个配方的目标。随着 makefile 变长,我有时会忘记在创建新配方后向all 添加新目标。

如果没有all 变量,Make 只会构建第一个目标及其先决条件。

如何从我的 Makefile 中删除这个重复源,并且如果它们的先决条件发生变化,仍然检查并重建所有配方目标?

DIR_DATA = ./data
DIR_RAW = $(DIR_DATA)/raw
DIR_MUNGE = ./munge

VPATH = $(DIR_RAW) $(DIR_DATA) $(DIR_MUNGE)

########################################################   
####################### Recipes ########################
########################################################

ds_mtcars.rds: ds_mtcars.R ds_mt_raw.csv
    Rscript $<

ds_mt_agg.rds: ds_mt_agg.R ds_mtcars.rds
    Rscript $<

ds_mt_temp.rds: ds_mt_temp.R ds_mtcars.rds ds_mt_agg.rds
    Rscript $<

########################################################   
####################### Phony vars #####################
########################################################    

.Phony: all 

all: ds_mtcars.rds ds_mt_agg.rds ds_mt_temp.rds 

clean: 
  rm -f ./data/*.rds

【问题讨论】:

    标签: makefile


    【解决方案1】:

    通常,您可以通过使用模式和列表来避免此类重复。在您的情况下,由于依赖项似乎不遵循简单的模式,因此您必须明确定义与文件关联的任何唯一依赖项。假设每个.rds 依赖于相应的.R 文件,您可以使用如下静态模式规则消除一些重复:

    RDS_FILES := ds_mtcars.rds ds_mt_agg.rds ds_mt_temp.rds
    
    all:
    
    # define any unique dependencies explicitly:
    ds_mtcars.rds: ds_mt_raw.csv
    ds_mt_agg.rds: ds_mtcars.rds
    ds_mt_temp.rds: ds_mtcars.rds ds_mt_agg.rds
    
    # use Static pattern rule -- 
    #  explicit dependencies will be stacked
    $(RDS_FILES) : %.rds : %.R
        Rscript $<
    
    .Phony: all
    all: $(RDS_FILES)
    

    您仍然需要在起始列表 (RDS_LIST) 和特殊依赖规则中列出每个具有特殊依赖关系的目标。

    【讨论】:

      最近更新 更多