omgimanerd
omgimanerd

Reputation: 125

makefile compile changed latex files in subdirectory

I am trying to create a makefile to compile LaTeX files in subdirectories. The desired directory structure should look like this, except instead of simply a, b, and c, there can be any number of subdirectories under the latex folder.

├── latex
│   ├── a
│   │   ├── output
│   │   │   └── stuff.pdf
│   │   └── stuff.tex
│   ├── b
│   │   ├── blah.tex
│   │   └── output
│   │       └── blah.pdf
│   └── c
│       ├── asdf.tex
│       └── output
│           └── asdf.pdf
└── makefile

I want to do this with only one makefile in the latex directory that will automatically compile the tex files in every subdirectory. My current makefile looks like this:

TEX_COMMAND = pdflatex

TEX_FILES = $(wildcard **/*.tex)

OUTPUT_DIRECTORIES = $(addsuffix output/,$(wildcard */))
PDF_FILES = $(join $(dir $(TEX_FILES)),$(addprefix output/,$(notdir $(TEX_FILES:tex=pdf))))

all: mkdir $(PDF_FILES)

mkdir:
    @mkdir -p $(OUTPUT_DIRECTORIES)

$(PDF_FILES): $(TEX_FILES)
    @$(TEX_COMMAND) -file-line-error -halt-on-error -output-directory $(dir $@) -aux_directory=$(dir $@) $(subst output/,$(notdir $(@:pdf=tex)),$(dir $@))
    @$(TEX_COMMAND) -file-line-error -halt-on-error -output-directory $(dir $@) -aux_directory=$(dir $@) $(subst output/,$(notdir $(@:pdf=tex)),$(dir $@))

clean:
    @rm -rf $(OUTPUT_DIRECTORIES)

This will correctly generate the proper pdf, aux, log, toc, etc. files in the output directory in each subdirectory. However, if I change one tex file, then make will cause everything to be recompiled.

I've already looked at many other similar questions. For other questions, the number of subdirectories is known, so you can hardcode them into the makefile. For this situation, the number of subdirectories in the latex folder is constantly changing and being added to, etc, which is why I'm using the wildcard to grab all the tex files. I would prefer not having to create a makefile for each subdirectory and using recursive make.

Upvotes: 1

Views: 1213

Answers (1)

Beta
Beta

Reputation: 99094

One of the fundamental shortcomings of Make is its crude handling of wildcards.

In this case, you can use secondary expansion to write a pattern rule that will do what you want:

all: mkdir $(PDF_FILES)

.SECONDEXPANSION:
%.pdf: $$(subst /output/,/, $$(subst .pdf,.tex, $$@))
    @echo buiding $@ from $<

Upvotes: 1

Related Questions