乳胶报告的 Makefile

乳胶报告的 Makefile

不确定这是否属于这里 - 但它困扰着我。我有一个 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 编译文档。

相关内容