Table of Contents

pdflatex

pdflatex is the most common LaTeX compiler.

You compile latex source code by running pdflatex main.tex. This creates a PDF file main.pdf. It also creates a log file main.log and an auxiliary file main.aux used to build references. You can ignore these latter two and rm -f *.aux *.log.

The following is a minimal latex source code you can use to try it out.

% Compile: pdflatex main.tex
% View:    xdg-view main.pdf
\documentclass{article}
\begin{document}
Hello world
\end{document}

Install

On Debian GNU/Linux, you install latex by installing texlive-latex-* packages. At a minimum, you should install texlive-latex-base and texlive-latex-extra. If you want everything, you can install texlive-full.

 $ apt install texlive-latex-base texlive-latex-extra

This will give you the pdflatex compiler + a myriad of useful packages. To give it a test, create a file main.tex with the following content,

\documentclass[a4paper]{article}
\usepackage{lipsum}
\begin{document}
\section{Introduction}
\lipsum[1-5]
\end{document}

Compile the document with pdflatex main.tex. You should see something of the following:

 $ pdflatex main.tex
This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2025/dev/Debian) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./main.tex
LaTeX2e <2024-11-01> patch level 2
L3 programming layer <2025-01-18>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2024/06/29 v1.4n Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texlive/texmf-dist/tex/latex/lipsum/lipsum.sty
(/usr/share/texlive/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty
(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)))
(/usr/share/texlive/texmf-dist/tex/latex/lipsum/lipsum.ltd.tex)) (./main.aux)

Package lipsum Warning: Unknown language 'latin'. Hyphenation patterns for
(lipsum)                'english' will be used instead.


[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}]
[2] (./main.aux) )</usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm
/cmbx12.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10
.pfb>
Output written on main.pdf (2 pages, 34145 bytes).
Transcript written on main.log.

When you list files with ls you should see 4 files

 $ ls
main.aux main.log main.pdf main.tex

At this point, you can safely ignore the *.log and *.aux files.

The resulting PDF contains 2 pages of random latin text. This text is Lorem ipsum. It's random gibberish used to test how a document looks like. It's provided by the \usepackage{lipsum} package which implements the \lipsum[1-5] command. [1-5] just defines how long should the text be. Because square bracket arguments are optional, you can use the command without any arguments like \lipsum, or you can specify different arguments like \lipsum[1-10].

Syntax error

When you make a syntax error, pdflatex shows you the error, but also expects you to fix the document interactively.

As an example, the following is a document that doesn't close a curly brace {.

\documentclass{article}
\begin{document}
Hello \textbf{World... oh no! Dropped a closing brace
\end{document}

When you run pdflatex main.tex

 $ pdflatex main.tex
This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2025/dev/Debian) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./main.tex
LaTeX2e <2024-11-01> patch level 2
L3 programming layer <2025-01-18>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2024/06/29 v1.4n Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)
(./main.aux))
Runaway argument?
{World.. oh no! Dropped a closing brace \end {document}
! File ended while scanning use of \textbf .
<inserted text>
                \par
<*> main.tex

?

At this point, pdflatex doesn't end and expects you to fix the document interactively. When you first encounter this, you'll likely find it frustrating to exit it. The way to exit it is to type in X and hit Enter. Or you press 'Ctrl + D' which sends an 'End of file' character to the program.

The interactive mode is annoying and you can disable it with -interaction=nonstopmode option.

 $ pdflatex -interaction=nonstopmode main.tex

Less output noise (texfot)

As you might have noticed pdflatex is extremely noisy. Most of its output is gibberish you probably don't care about. So a tool was created called texfot to cull the pdflatex clutter.

First, you have to install a package that provides it:

apt install texlive-extra-utils

Then you use it like so:

texfot pdflatex main.tex

Makefile

The following is a Makefile that compiles main.tex to build/main.pdf by running make. The build directory will also contain all the transient files *.aux *.log *.toc *.out and so on.

# Configuration
TARGET      := main
SOURCE      := $(TARGET).tex
OUTPUT      := $(TARGET).pdf
LATEX       := pdflatex
LATEX_FLAGS := -interaction=nonstopmode -halt-on-error -file-line-error
BUILD_DIR   := build
 
# Derived paths
BUILD_PDF   := $(BUILD_DIR)/$(OUTPUT)
BUILD_TEX   := $(BUILD_DIR)/$(SOURCE)
 
# Phony targets
.PHONY: all clean view vars
 
# Default target
all: $(BUILD_PDF)
 
# Build rules
$(BUILD_DIR):
	mkdir -p $(BUILD_DIR)
 
$(BUILD_TEX): $(SOURCE) | $(BUILD_DIR)
	cp $(SOURCE) $(BUILD_TEX)
 
$(BUILD_PDF): $(BUILD_TEX)
	cd $(BUILD_DIR) && $(LATEX) $(LATEX_FLAGS) $(SOURCE)
	cd $(BUILD_DIR) && $(LATEX) $(LATEX_FLAGS) $(SOURCE)
 
# Utility targets
clean:
	rm -rf $(BUILD_DIR)
 
view: $(BUILD_PDF)
	xdg-open $(BUILD_PDF) >/dev/null 2>&1 || open $(BUILD_PDF)
 
vars:
	@echo "TARGET=$(TARGET)"
	@echo "SOURCE=$(SOURCE)"
	@echo "OUTPUT=$(OUTPUT)"
	@echo "BUILD_DIR=$(BUILD_DIR)"

Usage: