ransford/pdflatex-makefile

Problem with linking figures

Closed this issue · 5 comments

Hi,

My figures are inside the Figures folder. So, in the make file I set FIGS=Figures and then I execute make. I get the following errors:

make: Circular Figures <- Figures dependency dropped.

make: *** No rule to make target '/%.svg', needed by 'Figures'.  Stop.

How would I fix them?

What does make --version say, and what is the layout of your directory? Are your input images SVG?

I have a root folder which has root.tex (master tex file). In the root, I put the Makefile and Makefile.include. Also, in the root I have multiple other folders like f1/ f2/ f3/ etc. and each f*/ has its corresponding .tex file like f1/f1.tex f2/f2.tex. etc. Then, in the root I have Figures/ in which I have a mix of svg, png, jpg images.

So, in the Makefile I put this:
FIGS= Figures
DEPS= f1/f1
DEPS+=f2//f2
.....

and in the Makefile.include I did TARGETS += $(DEP) right after TARGETS += $(TARGET) . I also get the warnings like::

grep: f1/f1.tex: No such file or directory

Are you able to post the entire Makefile? I'm still a little confused. I don't see how you'd get a circular dependency, and there's no mention of a $(DEPS) variable in Makefile.include.

image
So this is my directory.

This is my Makefile:

TARGET=Book  ## Name of root tex source
FIGS=Figures ## Name of the folder which stores Figures

#Front Matter
DEPS=Front_Matter/FM-Chapters

#Part-1
DEPS+=Part_1/part1
DEPS+=Introduction/Intro
DEPS+=Environment/Environment
DEPS+=Robots/Robots
DEPS+=SLAM/SLAM

#Part-2
DEPS+=Part_2/part2
DEPS+=Prelims/Prelims
DEPS+=GP/GP
DEPS+=Coverage_PP/Coverage_PP
DEPS+=Info_PP/Info_PP

#Part-3
DEPS+=Part_3/part3
DEPS+=Setup/Setup
DEPS+=Endurance_Est/Endurance_Est
DEPS+=Range_Est/Range_Est

#Part-4
DEPS+=Part_4/part4
DEPS+=Multi_robots/Multi_robots
DEPS+=Fusion/Fusion

#Part-5
DEPS+=SpatioTemp/SpatioTemp

#Part-6
DEPS+=Part_6/part6
DEPS+=Conclusion/Conclusion
DEPS+=Application_Algal_Bloom/Application_Algal_Bloom
DEPS+=Localization/Localization
DEPS+=Search_n_Rescue/Search_n_Rescue

#Back-Matter
DEPS+=Back_Matter/BM-Chapters

#Other instructions
include Makefile.include  ## Compile instructions for make

I added DEPS here to link other *.tex files from other folders which are added to preamble using \include{....} in Book.tex (this is my root tex source).

Then, I modified the Makefile.include like this:

PDFLATEX	   ?= pdflatex -halt-on-error -file-line-error -shell-escape
BIBTEX		   ?= bibtex
MAKEGLOSSARIES ?= makeglossaries
MAKENOMENCL    ?= makeindex

## String to find in log to check whether rerun is necessary
RERUN_PATTERN = Rerun to

ifneq ($(QUIET),)
PDFLATEX	+= -interaction=batchmode
ERRFILTER	:= > /dev/null || (egrep ':[[:digit:]]+:' *.log && false)
BIBTEX		+= -terse
else
PDFLATEX	+= -interaction=nonstopmode
ERRFILTER=
endif

## Action for 'make view'
OS=$(shell uname -s)
## For Ubuntu 16
ifeq ($(OS),Xenial) 
PDFVIEWER	?= evince
else
PDFVIEWER	?= xdg-open
endif

## Makefile to turn Book.tex into Book.pdf.
TARGETS += $(TARGET)
TARGETS += $(DEPS) 
TEXTARGETS = $(TARGETS:=.tex)
PDFTARGETS = $(TARGETS:=.pdf)
AUXFILES   = $(TARGETS:=.aux)
LOGFILES   = $(TARGETS:=.log)

## Inkscape SVG file processing:
ifeq ($(shell which inkscape >/dev/null 2>&1 && echo USING_INKSCAPE),USING_INKSCAPE)
  FIG_SVG=$(wildcard $(FIGS)/*.svg)
  FIG_PDF=$(FIG_SVG:.svg=.pdf)
else
  FIG_PDF=
endif

## If $(TARGET).tex refers to .bib files like \bibliography{foo,bar}, then
## $(BIBFILES) will contain foo.bib and bar.bib, and both files will be added as
## dependencies to $(PDFTARGETS).
## Effect: updating a .bib file will trigger re-typesetting.
BIBFILES += $(patsubst %,%.bib,\
		$(shell grep '^[^%]*\\bibliography{' $(TEXTARGETS) | \
			grep -o '\\bibliography{[^}]\+}' | \
			sed -e 's/^[^%]*\\bibliography{\([^}]*\)}.*/\1/' \
			    -e 's/, */ /g'))

## Add \input'ed or \include'd files to $(PDFTARGETS) dependencies; ignore
## .tex extensions.
INCLUDEDTEX = $(patsubst %,%.tex,\
		$(shell grep '^[^%]*\\\(input\|include\){' $(TEXTARGETS) | \
			grep -o '\\\(input\|include\){[^}]\+}' | \
			sed -e 's/^.*{\([^}]*\)}.*/\1/' \
			    -e 's/\.tex$$//'))

AUXFILES += $(INCLUDEDTEX:.tex=.aux)

## grab a version number from the repository (if any) that stores this.
## * REVISION is the current revision number (short form, for inclusion in text)
## * VCSTURD is a file that gets touched after a repo update
SPACE = $(empty) $(empty)
ifeq ($(shell git status >/dev/null 2>&1 && echo USING_GIT),USING_GIT)
  ifeq ($(shell git svn info >/dev/null 2>&1 && echo USING_GIT_SVN),USING_GIT_SVN)
    # git-svn
    ifeq ($(REVISION),)
      REVISION := $(shell git svn find-rev git-svn)
    endif
    VCSTURD := $(subst $(SPACE),\ ,$(shell git rev-parse --git-dir)/refs/remotes/git-svn)
  else
    # plain git
    ifeq ($(REVISION),)
      REVISION := $(shell git describe --always HEAD)
    endif
    GIT_BRANCH := $(shell git symbolic-ref HEAD 2>/dev/null)
    VCSTURD := $(subst $(SPACE),\ ,$(shell git rev-parse --git-dir)/$(GIT_BRANCH))
  endif
else ifeq ($(shell hg root >/dev/null 2>&1 && echo USING_HG),USING_HG)
  # mercurial
  ifeq ($(REVISION),)
    REVISION := $(shell hg id -i)
  endif
  VCSTURD := $(subst $(SPACE),\ ,$(shell hg root)/.hg/dirstate)
else ifeq ($(shell svn info >/dev/null && echo USING_SVN),USING_SVN)
  # subversion
  ifeq ($(REVISION),)
    REVISION := $(subst :,-,$(shell svnversion -n))
  endif
  VCSTURD := $(addsuffix /.svn/entries, $(shell svn info | grep 'Root Path' | sed -e 's/\(.*\:\)\(.*\) /\2/'))
endif

# .PHONY names all targets that aren't filenames
.PHONY: all clean pdf view snapshot distill distclean

all: pdf $(AFTERALL)

ifeq ($(shell which inkscape >/dev/null 2>&1 && echo USING_INKSCAPE),USING_INKSCAPE)
$(FIGS)/%.pdf: $(FIGS)/%.svg  ## Figures for the manuscript
	inkscape -C -z --file=$< --export-pdf=$@ 2> /dev/null
endif

pdf: $(FIG_PDF) $(PDFTARGETS)


view: @echo "Opening PDFVIEWER"
	$(PDFTARGETS)
	$(PDFVIEWER) $(PDFTARGETS)

# define a \Revision{} command you can include in your document's preamble.
# especially useful with e.g. draftfooter.sty or fancyhdr.
# usage: \input{revision}
#        ... \Revision{}
ifneq ($(REVISION),)
REVDEPS += revision.tex
revision.tex: $(VCSTURD)
	/bin/echo '\newcommand{\Revision}'"{$(subst _,\_,$(REVISION))}" > $@
AUXFILES += revision.aux
endif

# to generate aux but not pdf from pdflatex, use -draftmode
%.aux: %.tex $(REVDEPS)
	$(PDFLATEX) -draftmode $* $(ERRFILTER)

# specify KEEPAUX=1 if you need to keep auxiliary (.aux) files for some other
# tool (e.g., an autocompleting text editor)
ifneq ($(KEEPAUX),1)
  .INTERMEDIATE: $(AUXFILES)
endif

# introduce BibTeX dependency if we found a \bibliography
ifneq ($(strip $(BIBFILES)),)
BIBDEPS = %.bbl
%.bbl: %.aux $(BIBFILES)
	$(BIBTEX) $*
endif

# introduce makeglossaries dependency if we found \printglossary/ies
HAS_GLOSSARIES = $(shell \
		grep '^[^%]*\\printglossar\(ies\|y\)' $(TEXTARGETS) $(INCLUDEDTEX) && \
		echo HAS_GLOSSARIES)
ifneq ($(HAS_GLOSSARIES),)
GLSDEPS = %.gls
%.gls: %.aux
	$(MAKEGLOSSARIES) $(TARGETS)
endif

# introduce makenomenclature dependency if we found \printnomenclature
HAS_NOMENCL = $(shell \
		grep '^[^%]*\\printnomenclature' $(TEXTARGETS) $(INCLUDEDTEX) && \
		echo HAS_NOMENCL)
ifneq ($(HAS_NOMENCL),)
NLSDEPS = %.nls
%.nls: %.nlo
	$(MAKENOMENCL) $(TARGETS).nlo -s nomencl.ist -o $(TARGETS).nls
endif

$(PDFTARGETS): %.pdf: %.tex %.aux $(GLSDEPS) $(BIBDEPS) $(INCLUDEDTEX) $(REVDEPS) $(NLSDEPS)
	$(PDFLATEX) $* $(ERRFILTER)
ifneq ($(strip $(BIBFILES)),)
	@if egrep -q "undefined (references|citations)" $*.log; then \
		$(BIBTEX) $* && $(PDFLATEX) $* $(ERRFILTER); fi
endif
	@while grep -q "$(RERUN_PATTERN)" $*.log; do \
		$(PDFLATEX) $* $(ERRFILTER); done

DRAFTS := $(PDFTARGETS:.pdf=-$(REVISION).pdf)
$(DRAFTS): %-$(REVISION).pdf: %.pdf
	cp $< $@
snapshot: $(DRAFTS)

%.distilled.pdf: %.pdf
	gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$@ \
		-dCompatibilityLevel=1.5 -dPDFSETTINGS=/prepress -c .setpdfwrite -f $<
	exiftool -overwrite_original -Title="" -Creator="" -CreatorTool="" $@

distill: $(PDFTARGETS:.pdf=.distilled.pdf)

distclean: clean
	$(RM) $(PDFTARGETS) $(PDFTARGETS:.pdf=.distilled.pdf) $(EXTRADISTCLEAN)

clean:
	$(RM) $(foreach T,$(TARGETS), \
		$(T).nlo $(T).synctex.gz $(T).bbl $(T).bcf $(T).bit $(T).blg \
		$(T)-blx.bib $(T).brf $(T).fdb_latexmk \
		$(T).fls $(T).glg $(T).glo $(T).gls \
		$(T).glsdefs $(T).glx \ $(T).gxg \
		$(T).gxs $(T).idx $(T).ilg $(T).ind \
		$(T).ist $(T).loa $(T).lof $(T).lol \
		$(T).lot $(T).maf $(T).mtc* $(T).nav \
		$(T).out $(T).pag $(T).run.xml $(T).snm \
		$(T).svn $(T).tdo $(T).tns $(T).toc \
		$(T).vtc $(T).url) \
		$(REVDEPS) $(AUXFILES) $(LOGFILES) \
		$(EXTRACLEAN)

For the clean, you also had the $(FIG_PDF) but then I get the error cannot delete Figures/ with rm -f as it is a directory. I thought it was supposed to delete those pdf figs inside this folder that were converted from svg but it tries to delete the entire folder. I do not want to lose all my figs so I removed it for now.

Looks like the problem is TARGETS += $(DEPS), which essentially says "My outputs should include my inputs," and I think you can see the problem in that statement. :-)

I would recommend two things:

  • Revert Makefile.include so it matches the version we "ship" in this repository
  • Rather than trying to teach a Makefile about your dependencies by listing them in a variable ($(DEPS)), make Book.tex into a simple file like the block below:
\documentclass{...}
%% other stuff here (\usepackage etc.)
\begin{document}
\input{Front_Matter/FM-Chapters.tex}
\input{Part_1/part1.tex}
\input{Introduction/Intro.tex}
%% ... and the rest of your source files
\end{document}

Then after you get make to run (producing Book.pdf), touch one of the input files (e.g., Introduction/Intro.tex) and run make again and you'll see that it correctly notices that Book.pdf needs to be rebuilt. Then run make again without touching anything and you should see that it correctly determined that Book.pdf was already up to date.

The "magic" here is the INCLUDEDTEX part of Makefile.include, which parses your main input file (Book.tex) in search of \input or \include commands, adding to the set of dependencies as it finds them. As long as you're following the pattern of "one main file that mentions all its dependencies via \input or \include," the unmodified Makefile.include should work as designed.

I'm closing this issue because I think that should sort it out, but please reopen if you run into further trouble.