You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GNU Makefile中遍历嵌套目录下的TeX文件并实现增量PDF构建

使用GNU Make批量编译TeX文件并保持目录结构

需求回顾

你有这样的TeX文件目录结构:

input/
|
|-- one.tex
|-- two.tex
|-- sub1/
|   |
|   |-- three.tex
|   |-- four.tex
|-- sub2/
|   |
|   |-- five.tex
|   |-- six.tex

想要用pdflatex把每个.tex文件编译成xxx_out.pdf,并且在output目录下保持和input完全一致的子目录结构,最终得到:

output/
|
|-- one_out.pdf
|-- two_out.pdf
|-- sub1/
|   |
|   |-- three_out.pdf
|   |-- four_out.pdf
|-- sub2/
|   |
|   |-- five_out.pdf
|   |-- six_out.pdf

同时希望Make能自动检测.tex文件的修改,只更新对应的PDF。你写的Makefile只处理了第一个文件,核心问题是目标文件定义和实际输出不匹配,且缺少目录创建步骤。

原Makefile的问题分析

  1. 目标与实际输出不匹配:你定义的PDF_FILES是output/%.pdf,但实际用-jobname生成的是xxx_out.pdf,Make找不到预期目标文件,会出现重复执行或无法追踪所有文件的情况。
  2. 缺少输出目录创建:当output/sub1这类子目录不存在时,pdflatex无法生成文件到对应目录,导致编译失败。
  3. Jobname路径处理错误:$(addsuffix _out,$(basename $@))会生成类似output/one_out的路径,pdflatex会把文件生成在当前目录而非output下,进一步导致目标文件缺失。

修正后的Makefile

SOURCE_DIR := input
BUILD_DIR := output

# 递归查找所有.tex源文件
TEX_FILES := $(shell find $(SOURCE_DIR) -type f -name "*.tex")
# 生成对应的目标PDF路径:将input/xxx.tex映射为output/xxx_out.pdf
PDF_FILES := $(patsubst $(SOURCE_DIR)/%.tex, $(BUILD_DIR)/%_out.pdf, $(TEX_FILES))

.PHONY: all clean

all: $(PDF_FILES)

# 编译规则:每个output/xxx_out.pdf依赖于对应的input/xxx.tex
$(BUILD_DIR)/%_out.pdf: $(SOURCE_DIR)/%.tex
	# 自动创建目标文件所在的目录(多级目录也能一次性创建)
	mkdir -p $(@D)
	# 指定输出目录到目标文件路径,jobname取不带路径的文件名(比如three_out)
	pdflatex -output-directory=$(dir $@) -jobname=$(notdir $(basename $@)) $<

# 清理所有生成的PDF文件
clean:
	rm -rf $(BUILD_DIR)

关键说明

  • $(patsubst ...):精准映射源文件到目标文件,确保Make能正确追踪每个文件的依赖关系,实现增量编译。
  • mkdir -p $(@D):$(@D)代表目标文件所在的目录,-p参数自动创建多级目录,解决子目录不存在的问题。
  • pdflatex参数:-output-directory指定输出文件的存放目录,-jobname只取纯文件名,编译后的PDF会直接生成在预期的路径下,完美匹配目标文件。

其他可选方案(供参考)

如果你想简化流程,也可以试试这些工具:

  • latexmk:专门的TeX编译工具,支持自动处理依赖和目录结构,一行命令就能实现需求:
    find input -name "*.tex" -exec sh -c '
      texfile="$1"
      outdir="output/$(dirname "${texfile#input/}")"
      mkdir -p "$outdir"
      latexmk -pdf -jobname="${outdir}/$(basename "${texfile%.tex}_out")" "$texfile"
    ' sh {} \;
    
  • Shell脚本:用循环遍历所有.tex文件,手动处理目录和编译,适合简单场景,但没有Make的增量编译优势。

内容的提问来源于stack exchange,提问作者J...S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:57:42