我最近转换为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 $* > $@
但是上面的方法有两个问题:
Makefile是否适合执行此类任务?如果是,那么在makefile中指定此目标的Makefile最多的方法是什么?
答案 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 \
))