如何为makefile指定可选的依赖项

时间:2014-12-05 06:45:50

标签: parallel-processing makefile

我最近转换为GNU make use。我试图滥用Makefile进行各种文件操作,因为Makefile提供了并行性和检查点功能。这是我的问题:

我有很多pdf文件,我解析为csv。 pdf文件采用分层文件夹结构:

level1/
   level2_1/
      level3_1_1.pdf
      level3_1_2.pdf
   level2_2/
      level3_2_1.pdf
      level3_2_2.pdf

我的脚本符合规则:

%.csv: %.pdf
      python parsepdf.py $< $@

但是现在我想要连接所有这些文件。简单的方法是使用简单的查找脚本

cat $(find level1/ -name '*.csv') > level1/level1.csv

但是,我希望以跟随依赖关系层次结构的方式执行此操作,并在层次结构的每个级别创建中间csv。我假设这种方法将利用make -j的并行性优势。

level1/level2_1/level_2_1.csv : level1/level2_1/level3_1_1.csv level1/level2_1/level3_1_2.csv
         cat $* > $@
level1/level2_2/level_2_2.csv : level1/level2_2/level3_2_1.csv level1/level2_2/level3_2_2.csv
         cat $* > $@
level1/level1.csv : $(wildcard level1/level2_*.csv)
         cat $* > $@
但是上面的方法有两个问题:

  • 即使其中一个csv文件不存在,也不会创建高级csv文件。我的要求就是这样,即使有一个文件,我也应该继续创建一个升级的csv文件。
  • 如何在层次结构中为两个级别自动生成这些规则(确定只假设两个级别)。每个级别可以有不同数量的pdf文件。

Makefile是否适合执行此类任务?如果是,那么在makefile中指定此目标的Makefile最多的方法是什么?

1 个答案:

答案 0 :(得分:1)

我会猜测你想要什么,因为你的问题并不是很清楚。

使用find,通配符或$(wildcard)生成先决条件列表是一种不好的做法。躲开它。只需明确列出它们。如果你需要自动化这个过程,你总是可以让一些脚本最初为你生成Makefile,然后在必要时手动编辑它。

然后你可以

define CONCATENATE_RULE                                                         
$1: $2 Makefile                                                                 
        cat $2 > $1                                                             
endef                                                                           

$(eval $(call CONCATENATE_RULE, level1/level2_1/level_2_1.csv,\
    level1/level2_1/level3_1_1.csv \
    level1/level2_1/level3_1_2.csv \
))


$(eval $(call CONCATENATE_RULE, level1/level2_2/level_2_2.csv,\
    level1/level2_2/level3_2_1.csv \
    level1/level2_2/level3_2_2.csv \
))