[Tex/LaTex] Makefile for a latex report

makefile

Not sure if this belongs here – but its bugging me.
I have a 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

As can be seen, the current directory contains SI16-SC13B038.tex, which is the main tex file – there are other tex files in directories (stored in variables D1,D2,D3,D4) which are included in the main one.
I am using the nomencl package for nomenclatures and natbib for the bibliography (the references are in the directory name stored in DBIB).

The issue I am having is that the make file does not seem to evaluate dependencies – how many ever times I invoke make all the operations are done. Something's wrong with the makefile – help me out!

Best Answer

As @DavidCarlisle has indicated, if a .nlo gets recreated with each run, this causes an update of the .nls target, then of the .pdf target. But then .nlo has been updated again, so the cycle repeats every time you invoke make. To overcome that, you'd use a checksum file instead of the .nlo dependency, and touch the checksum file only if the .nlo file contents have changed. Here is an untested Makefile fragment:

$(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

Replace your rule for $(DOCNAME).nls with that.

Do not forget to append *.*-stamp *.*-stamp2 to the list of files to clean.

Note: If you copy-paste Makefile fragments, pipe them through unexpand to regenerate the TAB characters.


Instead of the above, I'd suggest using latexmk. It does such things properly and figures out all necessary program runs automatically.

With latexmk, a complete GNU Makefile generally looks like the following (just tune 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

This keeps track of dependencies automatically. Even if only an installed and used package file has changed, make triggers recompilation.

This is almost perfect. Almost because if you shadow a texmf-dist package with a local one, the changed dependency path is not detected automatically. It will however be recorded with the next TeX run.

To get the custom index files processed, add a latexmkrc file:

add_cus_dep('nlo', 'nls', 0, 'makenlo2nls');
sub makenlo2nls {
    system( "makeindex -o \"$_[0].nls\" -s nomencl.ist \"$_[0].nlo\"" );
}

BibTeX processing should work without extra configuration.

Related Question