Skip to content

Instantly share code, notes, and snippets.

@staticfloat
Created March 23, 2017 17:11
Show Gist options
  • Save staticfloat/b1f6c662f1cc7d24e970159712c46495 to your computer and use it in GitHub Desktop.
Save staticfloat/b1f6c662f1cc7d24e970159712c46495 to your computer and use it in GitHub Desktop.
Docker+Latex makefile
# This is the top-level filename. There should be a "$(TOP_LEVEL).tex" file
# sitting in this directory as well as a "$(TOP_LEVEL).bib" file for
# bibliographies, and it will produce a "$(TOP_LEVEL).pdf" file after running
# `make`. Tweak this to whatever you want.
TOP_LEVEL = generals
# Grab all the .tex files in this directory, so we can use them as dependencies
# in other rules. $(wildcard <foo>) will expand to the list of files that match
# the pattern "<foo>" using standard shell globbing rules
TEX_FILES = $(wildcard *.tex)
# We want to pass these arguments to Latex (which is done in our build rules
# below) so that, for example, all the build products (.aux, .log, .bbl, etc...)
# files are collected within the build/ directory
LATEX_OPTS = -output-directory=build --synctex=1
# This is the base of the docker command we're going to run. Breaking it down:
# `--rm`: Remove the container once you're done. Good housekeeping.
# `--user`: Set the user/group of the user inside of the docker contianer
# to the same as the user in your host machine, so there are no
# permissions problems. This doesn't matter on OSX BTW.
# `--net=none`: We're not using the network, don't bother to hook it up.
# `-v`: Mount the current directory (pwd) within the container so that
# latex can find it. We mount it at the same location within the
# container so that when synctex files get written out, the paths
# are the same within the container as without
# `-w`: We set the workdir to where we're putting our files.
#`blang/latex`: This is the name of the latex image that we run
# `/bin/bash`: The actual commands we give to latex are bash commands, so run
# /bin/bash inside of the container.
# `-c`: This is actually an option for bash, saying "the next thing is
# the commands I want you to run".
WORK_DIR=$(shell pwd)
DOCKER_CMD = docker run --rm --user=$(shell id -u):$(shell id -g) --net=none \
-v "$(WORK_DIR):$(WORK_DIR)" -w="$(WORK_DIR)" \
blang/latex /bin/bash -c
# You would use this variable like so:
# $(DOCKER_CMD) "pdflatex foo.tex bar.tex"
# and it would start up a docker container with the options we defined, then
# start bash within the container and feed it the command we put afterward,
# which in this case is `pdflatex` with some extra arguments included. You'll
# see us do this below in the makefile rules.
# The very first target in a makefile is the default target that gets built if
# there are no commands given to `make`. So our default target is to build
# the pdf we're interested in
default: build/$(TOP_LEVEL).pdf
# Now onto the more meaty stuff. `bibtex` doesn't let us use a build directory
# like we'd want, so we have to manually copy it into the build directory, then
# run `bibtex` from there. This of course, depends on the bib files themselves
# as well as the existence of the build directory
build/$(TOP_LEVEL).bbl: $(TOP_LEVEL).bib
@mkdir -p build
@# Copy top-level bib file to build/
@cp $(TOP_LEVEL).bib build/$(TOP_LEVEL).bib
@# Run pdflatex once, then bibtex ones, then pdflatex again
@$(DOCKER_CMD) "pdflatex $(LATEX_OPTS) $(TOP_LEVEL).tex && \
cd build && bibtex $(TOP_LEVEL) && cd .. && \
pdflatex $(LATEX_OPTS) $(TOP_LEVEL).tex"
# To build the actual pdf, depend on all the `.tex` files as well as the result
# of our bibtex run, to ensure that the bibtex output is updated whenever it
# needs to be. Also depend on the existence of the build directory
build/$(TOP_LEVEL).pdf: $(TEX_FILES) build/$(TOP_LEVEL).bbl build
@mkdir -p build
@$(DOCKER_CMD) "pdflatex $(LATEX_OPTS) $(TOP_LEVEL).tex && \
pdflatex $(LATEX_OPTS) $(TOP_LEVEL).tex"
@# We'll symlink this file into the root directory too, just for fun and ease
@ln -sf build/$(TOP_LEVEL).pdf $(TOP_LEVEL).pdf
# This will open up a shell in the same docker container your commands would be
# running in, to aid with debugging
shell:
$(DOCKER_CMD) "bash"
# This deletes the build directory and any other build artifacts
clean:
rm -rf build/ $(TOP_LEVEL).pdf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment