1

gnu make を使用して LaTeX ドキュメントをコンパイルしています。私は過去にそれを何度も行ってきましたが、今では 2 つの異なる形式でドキュメントをコンパイルする必要があります。私がやっていることの背景として、LaTeX ファイルにLaTeX 条件式を実装しました。ファイルの例を次に示します。

% TheTexFile.tex
% This accepts makefile definitions
%   \isTwoColumn
%   \isDoubleSpaced
\ifdefined\isTwoColumn
    \documentclass[letterpaper, twocolumn]{article}
\else
    \documentclass[letterpaper]{article}
\fi
%\documentclass[letterpaper]{article}
\ifdefined\isDoubleSpaced
  \usepackage{setspace}
  \doublespacing
\fi

\begin{document}
  Some document text for a document that should be able to be compiled using
  two different methods.  There seems to be a problem though, but OP thinks
  that it is in the makefile not in the LaTeX since it can be compiled using
  both methods by issuing the same commands that are in the makefile directly
  enter code here`from the command line.
\end{document}

私はこれらを別の make ターゲットを使ってコンパイルすることができますが、私はどちらか一方、通常は読みやすいバージョンしかコンパイルしていないため、常に人々に古いバージョンを送っていて、ほとんどの人は他のバージョンを見る必要があります。推奨事項。Makefileの質問に関するアドバイスに従いました。可能であればサブディレクトリの使用を避けたいという例外を除いて、異なるフラグで 2 回コンパイルされた同じソースからの 2 つのターゲット。それを念頭に置いて、次のmakefileを考え出しました。

# The makefile

# The targets
OBJS=TheTexFile.pdf

# The different build methods
DBL_SPACE_PREFIX=DBL_SPACE_
TWO_COL_PREFIX=TWO_COL_
DBL_SPACE_OBJS=$(addprefix $(DBL_SPACE_PREFIX), $(OBJS))
TWO_COL_OBJS=$(addprefix $(TWO_COL_PREFIX), $(OBJS))

# A variable for defining the job information (output files)
JOBNAME=$(shell echo $@ | sed 's/\.pdf//')

all: $(TWO_COL_OBJS) $(DBL_SPACE_OBJS) clean

$(DBL_SPACE_PREFIX)%.pdf: TEXDEF=\def\isDoubleSpaced{1}
$(TWO_COL_PREFIX)%.pdf: TEXDEF=\def\isTwoColumn{1}

$(DBL_SPACE_PREFIX)%.pdf $(TWO_COL_PREFIX)%.pdf: %.tex

    pdflatex -jobname=$(JOBNAME) -shell-escape --enable-write18 "$(TEXDEF) \input{$<}"
    pdflatex -jobname=$(JOBNAME) -shell-escape --enable-write18 "$(TEXDEF) \input{$<}"
    bibtex $(JOBNAME)
    pdflatex -jobname=$(JOBNAME) -shell-escape --enable-write18 "$(TEXDEF) \input{$<}"
    pdflatex -jobname=$(JOBNAME) -shell-escape --enable-write18 "$(TEXDEF) \input{$<}"

.PHONY: clean
clean:
    # Get rid of pdflatex files
    rm *.aux *.bbl *.blg *.log *.nav *.out *.snm *.toc

.PHONY: cleanall
cleanall:
    rm $(DBL_SPACE_OBJS) $(TWO_COL_OBJS)

これはほぼ完璧に機能します。この問題は、すべてのターゲットが削除されていることを確認したときに発生します。つまり、コマンドmake cleanandを発行してmake cleanallから を発行しmakeます。最初は、 のみTWO_COL_OBJSがコンパイルされます。すべてのターゲットをそのままにしてコマンドを再発行すると、DBL_SPACE_OBJSコンパイルされます。これですべてのオブジェクトがコンパイルされましたが、同じコマンドを 2 回発行する必要がありました。これは回避したかったことです。

同様に、 のターゲット オブジェクトを逆にするとall、つまり

all: $(TWO_COL_OBJS) $(DBL_SPACE_OBJS) clean

になる

all: $(DBL_SPACE_OBJS) $(TWO_COL_OBJS) clean

DBL_SPACE_OBJS1回目も2回目も全て頂きますTWO_COL_OBJS。私は何が欠けていますか?

4

1 に答える 1

2

cleanまず、ルールをルールの前提条件にしたくないと思いallませんか?

とにかく、このままではいけません。複数のターゲットを持つパターン ルールは、ルールが 1 回だけ実行されることを意味します。1 回実行すると、メイン ターゲットが 1 つ作成され、残りのターゲットは副作用として作成されます。メイン ターゲットのみがターゲット固有のパターン変数に対してチェックされるため、TEXDEF 値はその値の 1 つにのみ設定されます。これが、出力が 1 つしか得られない理由です。すべての異なるターゲットがターゲット固有のパターン変数に対してチェックされることが事実であったとしても、コマンドの 1 つにはある値が必要であり、もう 1 つのコマンドには別の値が必要であることをどのように make が知ることができるでしょうか? 考えてみれば、これは仕方のないことです。

代わりに、各タイプの出力を構築するために 1 つずつ、 2 つの異なるパターン ルールを作成する必要があります。これを書く必要があります (JOBNAME はもう必要ないことに注意してください。ただし、たとえ必要だったとしても、サフィックスを削除するためだけにシェルを使用する必要はありません...):

$(DBL_SPACE_PREFIX)%.pdf: %.tex
        pdflatex -jobname=$@ -shell-escape --enable-write18 "$(TEXDEF) \input{$<}"
        bibtex $@
        pdflatex -jobname=$@ -shell-escape --enable-write18 "$(TEXDEF) \input{$<}"

$(TWO_COL_PREFIX)%.pdf: %.tex
        pdflatex -jobname=$@ -shell-escape --enable-write18 "$(TEXDEF) \input{$<}"
        bibtex $@
        pdflatex -jobname=$@ -shell-escape --enable-write18 "$(TEXDEF) \input{$<}"

これらをさらに組み合わせたい場合は、レシピを変数に入れて、それを両方のルールで使用できます。

于 2013-06-26T22:00:03.897 に答える