Makefile中如何让Glob命令在文件生成后再执行?
解决Makefile中pdfunite无法获取动态生成PDF文件的问题
在使用Makefile调用pdfunite合并由cardito生成、经inkscape转换的PDF文件时,遇到了$(shell ls out/*.pdf)提前执行导致返回空值的问题。这是因为Make的$(shell)函数在解析Makefile阶段就会运行,而此时inkscape还未完成SVG到PDF的转换,PDF文件尚未生成。
方案1:使用Shell命令替换(动态获取文件列表)
将原pdfunite行中的Make$(shell)函数替换为Shell的命令替换(注意转义$为$$),让Shell在命令执行阶段(此时PDF已生成)动态获取文件列表:
修改后的pdf目标代码:
pdf: cardfiles - rm out/all_cards.pdf for f in out/*.svg ; do \ inkscape --export-type=pdf $$f ; \ done; pdfunite $$(ls out/*.pdf) out/all_cards.pdf
方案2:直接使用Shell通配符(更简洁)
无需调用ls,直接使用out/*.pdf,Make会将未匹配到的通配符原封不动传给Shell,Shell在执行时会自动展开已生成的PDF文件:
pdf: cardfiles - rm out/all_cards.pdf for f in out/*.svg ; do \ inkscape --export-type=pdf $$f ; \ done; pdfunite out/*.pdf out/all_cards.pdf
可选优化:添加文件存在检查
为避免因未生成PDF导致pdfunite报错,可在执行pdfunite前添加检查逻辑:
pdf: cardfiles - rm out/all_cards.pdf for f in out/*.svg ; do \ inkscape --export-type=pdf $$f ; \ done; if [ -z "$$(ls out/*.pdf 2>/dev/null)" ]; then \ echo "Error: No PDF files generated in out/ directory"; \ exit 1; \ fi pdfunite out/*.pdf out/all_cards.pdf
内容的提问来源于stack exchange,提问作者Matt Stoodley
相关产品推荐
相关产品推荐

