Make

ここでは、Make を LaTeX と組み合わせて使う方法を説明します。

Make とは何か?

Make は、定型的なファイル変換作業を自動化するツールです。 LaTeX では Make を使うことで、texソースファイルからPDFやdviファイルを生成する作業を自動化できます。

Make はUNIX 用のユーティリティツールとして古い歴史を持ち、さまざまな実装があります。 その中で現在多く用いられているのは、GNU Make です。 使い方や設定ファイル(Makefile)の文法は、基本的な部分は統一されているものの、実装ごとの拡張機能もあります。 特にGNU Makeは多くの拡張機能を持っています。

なお、一般に Make はC言語などのプログラムをコンパイルするときに多く用いられます。 Make について調べるとこうしたプログラムのコンパイルを前提とした情報が出てくることが多いので、注意してください。

Make のインストール

macOS

Xcode のコマンドラインツールをインストールしてください(http://qiita.com/ksato9700/items/8a14189934c9360a668c 参照)。 GNU Make がインストールされます。

Linux

多くの場合、初期状態で GNU Make がインストールされています。

FreeBSDなど

初期設定では、BSD Make がインストールされています。 下記の Makefile などが思うように動作しない場合は、GNU Makeのインストールも検討してください。 なお、GNU Makeが「make」ではなく「gmake」コマンドとしてインストールされている場合もあります。

Windows

Windows 用 の GNU Make のインストールをしてください。 MinGWCygwin などをインストールすれば GNU Make もインストールされます。

なお、Windows用のMakeにはGNU Makeのほか、マイクロソフト社のnmakeなどがあります。nmakeは、Visual Studioに付属します。

Makeの使い方

Makefile の作成と Make の実行

Makeを実行してTeXソースファイルからPDFや.dviなどのドキュメントファイルを生成する手順は、次のとおりです。

  1. texソースファイルと同じディレクトリーに「Makefile」という名前の設定ファイルを作成する
  2. texソースファイルと同じディレクトリーで、make コマンドを実行する

Makefile の作成

Makefile は、Make 設定ファイルの文法に従って記述します。 基本的な文法は次のとおりです。

ターゲット: 必須項目
<タブ>コマンド

ターゲットは、生成されるファイルの名前です。 1つの Makefile で複数のターゲットを指定することもできます。 その場合、make コマンド実行時に「make ターゲット」とすることで生成するファイルを設定できます。 ターゲットを指定せずに make コマンドを実行すると、Makefile で最初に指定されたターゲットが生成されます。 また通常は、ターゲットのファイルがすでに存在して更新日時がすべての必須項目ファイルの更新日時よりも新しい場合、ターゲットファイルの更新は不要と判断され、コマンドは実行されません。

必須項目は、ターゲット生成のために必要なファイルです。 1つのターゲットに対して複数の必須項目を指定できます。 必須項目のファイルが別の部分でターゲットとして指定されている場合、まずはそのファイルが生成されます。

コマンドは、必須項目からターゲットを生成するためのコマンドです。なおコマンドの前に付ける<タブ>は、スペースに変えると正常に動作しません。

基本的な Makefile

例として、『LaTeX2e 美文書作成入門 改訂第6版』P.31 の test.tex ファイルの \documentclass{jsarticle} を \documentclass[uplatex]{jsarticle} に変更したものが ~/latex ディレクトリーに作成してある状態から PDF を生成することを考えます。 まずはテキストエディタなどを使い、test.tex と同じディレクトリーに Makefile を次の内容で作成します。

test.pdf: test.dvi
	dvipdfmx $<
test.dvi: test.tex
	uplatex -interaction=batchmode $<

コマンド中の「$<」は必須項目を表し、この場合は「test.dvi」と「test.tex」になります。 なお、makeからuplatexコマンドを呼び出しているときにエラーが発生しても途中で止まらないよう、uplatexコマンドにオプション「-interaction=batchmode」を付けています。

Make の実行

Makefile を保存したあとターミナル上で test.tex のディレクトリーで make コマンドを実行します。Makefile に記述したコマンドが呼び出され、PDFが生成されます。 このあとは、test.tex が更新されたり生成された test.pdf が削除されたりしなければ、再度make コマンドを実行しても、Makefile に記述したコマンドは呼び出されません。 macOS や Linux 上でのコマンド実行例を以下に示します($ は、プロンプト文字)。

$ cd ~/latex/
$ ls
Makefile  test.tex
$ make
uplatex  -interaction=batchmode test.tex
This is e-upTeX, Version 3.14159265-p3.4-u1.11-130605-2.6 (utf8.uptex) (TeX Live 2014/dev)
 restricted \write18 enabled.
entering extended mode
dvipdfmx test.dvi
test.dvi -> test.pdf
[1]
25751 bytes written
$ ls
Makefile  test.aux  test.dvi  test.log	test.pdf  test.tex
$ make
make: `test.pdf' is up to date.
$

より実用的な Makefile

より実用的な Makefile として、次の内容が考えられます。

TARGET := test.pdf
.PHONY: all clean distclean
all: $(TARGET)
clean:
	$(RM) *.aux *.log *.dvi
distclean: clean
	$(RM) $(TARGET)
%.pdf: %.dvi
	dvipdfmx $<
%.dvi: %.tex
	uplatex -interaction=batchmode $<

「%.dvi: %.tex」のように記述されている行はパターンルールといい、拡張子を元に動作ルールを決めます。 「%.dvi: %.tex」は任意の.texファイルから.dviファイル、「%.pdf: %.dvi」は任意の.dviファイルから.pdfファイルを作成するルールを定めています。

この Makefile では次の機能を実現しています。

LaTeX実行時に多数生成される中間ファイルを削除するとき、手動で行うと誤って必要なファイルを削除してしまうなどのトラブルが起こる可能性があります。make clean や make distclean を設定して用いれば、こうしたトラブルを減らすことができます。

ただし、この Makefile では次のような場合に正常に動作しない可能性があります。

相互参照や目次などが含まれる場合

ドキュメントに次のものが含まれる場合、上記の Makefile ではいずれの場合でも正常にPDFを生成できません。これらを正常に生成するには、複数回LaTeXを実行する必要があるからです。

一般に、LaTeX を実行する回数を多くすれば正常にPDFを作成できない問題が発生する可能性は小さくなる反面、実行には時間がかかるというトレードオフの関係があります。

LaTeX を無条件に複数回実行

正常にPDFを作成できない問題の単純な解決方法は、無条件に複数回 LaTeXを実行することです。次の Makefile では変数 CNT で設定された回数(初期状態では2回)、無条件に LaTeX が実行されます。

TARGET := test.pdf
CNT := 2
.PHONY: all clean distclean
all: $(TARGET)
clean:
	$(RM) *.aux *.log *.dvi
distclean: clean
	$(RM) $(TARGET)
%.pdf: %.dvi
	dvipdfmx $<
%.dvi: %.tex
	for i in `seq 1 $(CNT)`; do uplatex -interaction=batchmode $<; done

Makeの実行方法は、基本的なMakefileの場合と同じです。作成されたPDFファイルで、特に相互参照や目次などの問題がないか確認してください。

この方法でも、LaTeX 実行の回数がまだ足りず、引き続きPDFが正常に作成できない場合もあります。そのときは、変数 CNT の数を増やします。 また、逆に LaTeX 実行の回数が多すぎるため、余計に時間がかかることも考えられます。

ログファイルに警告のある場合の実行

LaTeX を無条件で実行してから、ログファイルに警告がある場合にだけさらに LaTeX を実行することもできます。 次のMakefileでは、CNT 変数で指定された回数分LaTeX を実行してから、ログに相互参照未定義の警告がある場合だけLaTeXを実行するようにしています。 ログに相互参照未定義の警告があるかどうかは、shシェルのif文と grep(fgrep) を組み合わせて判定しています。 また、相互参照に誤りがある場合はLaTeXを何回実行してもログに相互参照未定義の警告が出るので、相互参照未定義の警告がある場合のLaTeX実行は最大3回としています。

TARGET := test.pdf
CNT := 2
.PHONY: all clean distclean
all: $(TARGET)
clean:
	$(RM) *.aux *.log *.dvi
distclean: clean
	$(RM) $(TARGET)
%.pdf: %.dvi
	dvipdfmx $<
%.dvi: %.tex
	for i in `seq 1 $(CNT)`; do uplatex -interaction=batchmode $<; done
	for i in `seq 1 3`; do if grep -F 'Rerun to get cross-references right.' `basename $< .tex`.log; then uplatex -interaction=batchmode $<; else exit 0; fi; done

なお、LaTeXを複数回実行する方法の詳細については、『LaTeX2e美文書作成入門』P.161の「(p)LaTeXを適切な回数繰り返し実行する方法 」を参照してください。

画像やLaTeXファイルが挿入されている場合

Makeは基本的に、必須項目として指定されているファイルが更新された場合に実行されます。 LaTeXソースファイルで \includegraphics 命令によって挿入された画像や、\include や \input 命令で挿入された LaTeX ファイルが更新されていても、上記の Makefile では Make が実行されず反映されないことがあります。

さらに、PDF, PNG, JPEG 形式の画像ファイルを挿入しているときは、バウンディング情報が必要です。

そのため、画像ファイルおよびLaTeXファイルの依存関係は、Makefileに反映する必要があります。 たとえば、画像 tiger.pdf を挿入している場合は、次のようにMakefileを記述します。 「test.dvi: tiger.pdf」が、画像ファイルの依存関係を表します。

TARGET := test.pdf
CNT := 1
.PHONY: all clean distclean
all: $(TARGET)
test.dvi: tiger.pdf
clean:
	$(RM) *.aux *.log *.dvi
distclean: clean
	$(RM) $(TARGET)
%.pdf: %.dvi
	dvipdfmx $<
%.dvi: %.tex
	for i in `seq 1 $(CNT)`; do uplatex -interaction=batchmode $<; done
	for i in `seq 1 3`; do if grep -F 'Rerun to get cross-references right.' `basename $< .tex`.log; then uplatex -interaction=batchmode $<; else exit 0; fi; done

挿入された画像やLaTeXファイルの調査

挿入された画像ファイルやLaTeXファイルを調査するためには、LaTeXソースファイルを直接さがす方法と、.flsファイルを使う方法があります。

ソースファイルの調査

挿入された画像ファイルやLaTeXファイルを調査するときは、LaTeXソースファイルを手動(目視)でさがすほかに、sed をつかってリスト出力することもできます。

次の例では、test.texファイルから \includegraphics 命令で指定された画像ファイルのリストを出力します。ただし、コメントやverbatim環境内などに記述された画像ファイルもリストに含まれるため、それらは除外する必要があります。

$ sed -e 's/}/}%/g' test.tex | sed -e 'y/}%/}\n/' | sed -n -e 's/.*\\includegraphics\(\[[^]]*\]\)\{0,1\}{\([^}]*\)}$/\2/p'

.flsファイルの調査

LaTeXに -recorderオプションをつけて実行すると出力される.fls ファイルを元に調査することもできます。次のコマンドで、test.tex ファイルからtest.fls ファイルを生成します。

$ uplatex -interaction=nonstopmode -recorder test.tex

.flsファイルには、LaTeX処理で入出力されるファイルがリストになっています。入力ファイルと出力ファイルはそれぞれ、INPUTとOUTPUTではじまる行に記録されます。また、TeXのシステムファイルもリストに含まれます。そのため、TeXのシステムファイル以外の入力ファイルを表示するには、 次のようにします。

$ grep '^INPUT' test.fls | grep -v `kpsewhich -expand-var '$TEXMFROOT'` | sort | uniq
INPUT test.aux
INPUT test.tex
INPUT tiger.pdf
INPUT tiger.xbb

PDF作成の実例

Make は、コマンド実行時のカレントディレクトリにある Makefile を読み込んで、その記述と引数に応じた処理を行います。以下に、LaTeX 文書の処理に用いた Makefile の実例を示します。

FILENAME  = doc001
TEX       = $(FILENAME).tex
IDX       = $(FILENAME).idx
DVI       = $(FILENAME).dvi
PDF       = $(FILENAME).pdf
PDFOUT    = $(FILENAME)_enc.pdf
all:
	make tex
	make tex
	make idx
	make tex
	make dvipdf
	make pw
distclean:
	make clean
	rm $(PDFOUT)
clean:
	rm *.aux *.dvi *.idx *.ilg *.ind *.log *.out *.toc *~ $(PDF)
tex:
	uplatex $(TEX)
idx:
	makeindex $(IDX)
dvipdf:
	dvipdfmx $(DVI)
pw:
	pdftk $(PDF) output $(PDFOUT) owner_pw foobar

この場合、用意した LaTeX 文書ファイルは doc001.tex という名前です。makeindex コマンドで索引を生成するのと、pdftk でコピー・ペースト・印刷の禁止、パスワードの付与を行うために、

という順番での処理を行う必要があります。 また、処理終了後、あるいは処理を中断するときには、中間生成ファイルや PDF 等を必要に応じて削除する必要があります。

このようなときに、上のような Makefile を作成しておくと、

$ make

(厳密には make all ですが、make は引数なしで実行されたときの default として、Makefile に最初に記述のある "all" を引数にとったときと同じ処理をします)と入力するだけで、上述の一連の処理が全て行われます。 また、

$ make clean

と入力すると、文書ファイルと最終生成物である PDF ファイル以外の全てのファイルが削除され、

$ make distclean

で、文書ファイル以外の全てのファイル(最終生成物の PDF ファイルを含めて)が削除されます。

リンク

Makefile の書き方は簡単な条件分岐なので、ご覧になるだけでも何となくお分かりになると思います。 ネット上では、"Makefile 書き方" で検索していただければ数多くの解説を参照することができると思います。 ここでは参考に以下ひとつだけ挙げておきます(append 歓迎)。

関連項目

Make と LaTeX の組み合わせとして次のようなものもあります。

Latexmk

Latexmk - TeX Wiki を参照.

OMake → 問題が発生する場合は Latexmk を使用する

http://omake.metaprl.org/

arara

Lua スクリプト

Ruby スクリプト

Perl スクリプト

バッチファイル


Last-modified: 2017-06-15 (木) 22:57:04 (369d)