Reputation: 125
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
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