如何在Makefile中实现自动遍历.gv文件转PDF的目标?
解决Makefile中images目标的自动遍历转换问题
看起来你遇到的核心问题是:images 目标依赖的是还未生成的 .gv 文件,而且你的PDF转换规则没有正确指向 images 目录下的目标文件。下面给你两种解决方案,分别适配不同的需求:
方案一:纯Make风格(支持增量编译)
这种方式利用Make的规则依赖特性,只重新转换修改过的 .gv 文件,效率更高:
# COMPILATION CC=gcc CFLAGS=-Wall -ansi -pedantic # DOSSIERS SOURCEDOC=sourcedoc DOC=doc SRC=src INC=inc OBJ=build FIGS=images # 动态生成PDF文件列表(会自动匹配images目录下的所有.gv对应的.pdf) PDF_FILES = $(patsubst $(FIGS)/%.gv, $(FIGS)/%.pdf, $(wildcard $(FIGS)/%.gv)) .PHONY: clean doc archive author all generate-gv .SILENT : clean # Targets all : clean test images test : $(OBJ)/Test_arbre.o $(OBJ)/aux.o $(OBJ)/Affichage.o $(OBJ)/ArbreBinaire.o $(OBJ)/arbres.o $(CC) $^ -o $@ $(CFLAGS) figures : $(OBJ)/figures.o $(OBJ)/Affichage.o $(OBJ)/ArbreBinaire.o $(OBJ)/aux.o $(OBJ)/arbres.o $(CC) $^ -o $@ $(CFLAGS) # 新增规则:运行figures生成.gv文件,并用标记文件记录生成状态 generate-gv: figures ./figures # 确保你的figures程序将.gv文件输出到$(FIGS)目录,若路径不对请调整 touch $(FIGS)/.gv-generated # 标记文件,让Make知道.gv已生成 # 修改images目标:先生成.gv,再生成所有PDF images : generate-gv $(PDF_FILES) # 修正PDF转换规则:明确目标是images目录下的.pdf文件 $(FIGS)/%.pdf: $(FIGS)/%.gv $(FIGS)/.gv-generated dot -Tpdf -o $@ $^ #=========== Objets =========== $(OBJ)/arbres.o : $(INC)/arbres.h $(INC)/aux.h $(INC)/Affichage.h $(INC)/ArbreBinaire.h $(OBJ)/Affichage.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h $(OBJ)/exemple*_arbre.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h $(OBJ)/aux.o : $(INC)/aux.h $(OBJ)/figures.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h $(INC)/arbres.h $(OBJ)/Test_arbre.o : $(INC)/arbres.h $(INC)/ArbreBinaire.h $(INC)/Affichage.h # Dummy rule $(OBJ)/%.o : $(SRC)/%.c @mkdir -p $(@D) @$(CC) $< $(CFLAGS) -I $(INC)/ -c -o $@ # Miscellaneous clean: rm -f *~ */*~ rm -rf __pycache__ src/__pycache__ rm -rf $(DOC) rm -f $(PROJECT)_$(AUTHOR12)_$(AUTHOR22).zip rm -f conf.py-e rm -rf $(OBJ) rm -f $(FIGS)/*.pdf $(FIGS)/*.gv $(FIGS)/.gv-generated # 删除标记文件 rm -f test
方案说明:
generate-gv目标负责编译并运行figures程序生成.gv文件,同时创建一个标记文件.gv-generated,让Make感知到.gv文件已生成。PDF_FILES自动匹配images目录下所有.gv文件,并生成对应的.pdf路径。- 修正后的
$(FIGS)/%.pdf规则明确将PDF输出到images目录,并且依赖标记文件,确保只有.gv文件生成后才会执行转换。
方案二:Shell循环简化版(快速解决)
如果你不需要增量编译,只是想快速实现遍历转换,直接在 images 目标中用Shell循环即可:
# ... 保留原有其他代码 ... images : figures ./figures # 运行程序生成.gv文件 # 遍历所有.gv文件转换为pdf for gv_file in $(FIGS)/*.gv; do \ if [ -f "$$gv_file" ]; then \ dot -Tpdf -o "$${gv_file%.gv}.pdf" "$$gv_file"; \ fi \ done # ... 保留原有其他代码 ...
方案说明:
这种方式无需复杂的Make规则,直接通过Shell遍历目录下的所有 .gv 文件进行转换,适合快速验证功能,但每次运行都会重新转换所有文件,没有增量编译的优势。
关键问题修正点:
- 原来的
%.pdf规则目标是当前目录的.pdf,而你需要的是images目录下的文件,所以必须写成$(FIGS)/%.pdf。 - 必须确保在转换PDF前,先运行
figures程序生成.gv文件,否则Make会因为找不到依赖文件而跳过转换步骤。
内容的提问来源于stack exchange,提问作者olirwin
相关产品推荐
相关产品推荐

