不确定这是否属于这里 - 但它困扰着我。我有一个 makefile:
DOCNAME=SI16-SC13B038
D1=Abstract
D2=Bonafide
D3=Declaration
D4=Introduction
DBIB=References
TEXDEP=$(D1)/*tex $(D2)/*tex $(D3)/*tex $(D4)/*tex
all: $(DOCNAME).pdf
$(DOCNAME).pdf: $(DOCNAME).tex $(TEXDEP) $(DOCNAME).nls $(DOCNAME).bbl
pdflatex $(DOCNAME) && pdflatex $(DOCNAME)
$(DOCNAME).nls: $(DOCNAME).nlo
makeindex $^ -s nomencl.ist -o $@
$(DOCNAME).nlo: $(DOCNAME).tex $(TEXDEP)
pdflatex $(DOCNAME)
$(DOCNAME).bbl: $(DOCNAME).tex $(TEXDEP) $(DBIB)/*bib
pdflatex $(DOCNAME) && bibtex $(DOCNAME)
.PHONY: clean
clean:
rm -f *.pdf *.bbl *.nlo *.nls
可以看出,当前目录包含 SI16-SC13B038.tex,这是主 tex 文件 - 目录中还有其他 tex 文件(存储在变量 D1、D2、D3、D4 中),它们包含在主目录中。我使用 nomencl 包来命名术语,使用 natbib 来参考书目(参考文献位于存储在 DBIB 中的目录名中)。
我遇到的问题是 make 文件似乎没有评估依赖关系 - 无论我调用 make 多少次,所有操作都已完成。makefile 出了问题 - 帮帮我吧!
答案1
正如 @DavidCarlisle 所指出的,如果.nlo
每次运行时都重新创建,则会导致更新目标.nls
,然后更新.pdf
目标。但是然后.nlo
又被更新了,所以每次调用时都会重复这个循环make
。为了克服这个问题,你应该使用校验和文件而不是依赖项.nlo
,并且只有当文件内容发生变化时才触碰校验和文件.nlo
。这是一个未经测试的 Makefile 片段:
$(DOCNAME).nls: $(DOCNAME).nlo-stamp
makeindex -s nomencl.ist -o $@ $(DOCNAME).nlo
$(DOCNAME).nlo-stamp: $(DOCNAME).nlo
sha1sum $^ >$@2
if cmp -s $@2 $@; then rm $@2; else mv -f $@2 $@; fi
$(DOCNAME).nls
用那个替换你的规则。
不要忘记将其附加*.*-stamp
*.*-stamp2
到要清理的文件列表中。
笔记:如果您复制粘贴 Makefile 片段,请通过管道传输它们unexpand
以重新生成 TAB 字符。
除了上述方法,我建议使用
latexmk
。它可以正确地完成这些事情,并自动找出所有必要的程序运行。
有了latexmk
,一个完整的 GNU Makefile 通常如下所示(只需调整DOCNAME
):
# Tools
LATEXMK = latexmk
RM = rm -f
# Project-specific settings
DOCNAME = basename-of-your-main-document
# Targets
all: doc
doc: pdf
pdf: $(DOCNAME).pdf
# Rules
%.pdf: %.tex
$(LATEXMK) -pdf -M -MP -MF $*.d $*
mostlyclean:
$(LATEXMK) -silent -c
$(RM) *.bbl
clean: mostlyclean
$(LATEXMK) -silent -C
$(RM) *.run.xml *.synctex.gz
$(RM) *.d
.PHONY: all clean doc mostlyclean pdf
# Include auto-generated dependencies
-include *.d
这会自动跟踪依赖关系。即使只有一个已安装并使用的包文件发生了变化,
make
也会触发重新编译。
这几乎是完美的。几乎因为如果你texmf-dist
用本地包来隐藏包,改变的依赖路径不会被自动检测到。但它会在下一次 TeX 运行中被记录下来。
为了处理自定义索引文件,请添加一个latexmkrc
文件:
add_cus_dep('nlo', 'nls', 0, 'makenlo2nls');
sub makenlo2nls {
system( "makeindex -o \"$_[0].nls\" -s nomencl.ist \"$_[0].nlo\"" );
}
BibTeX 处理无需额外配置即可进行。
答案2
Makefile 并不适合编译 TeX 文件。有一个特殊的程序 LatexMk 可以正确编译并正确理解依赖项。要按原样使用它:latexmk -pdf file.tex
如果您确实需要将其放入Makefile
,LatexMk 的手册页给出了以下建议:
.PHONY : all FORCE_MAKE
all : talk.pdf
%.pdf: %.tex FORCE_MAKE
latexmk -pdf $<
使用phony 目标FORCE_MAKE
强制目标始终由 Make 构建,以便实际调用 LatexMk。这样您就不必自己在复杂的 TeX 文档中指定依赖项,仍然可以使用 Make 编译文档。