> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/ja/narejjibsu/064-how-does-overleaf-compile-my-project.md).

# Overleafはどのようにプロジェクトをコンパイルしますか？

## LaTeXコンパイルの自動化

目次、図表一覧、相互参照、用語集、索引、文献引用などの機能をサポートするため、LaTeX はマルチパスの組版処理を使います。あるパス（コンパイル）で生成されたデータはファイルに書き出され、必要に応じて後続のパスの入力として使われます。次の動画では、Overleaf プロジェクトで「再コンパイル」ボタンをクリックするたびに何が起こるかを示します:

{% embed url="<https://videos.ctfassets.net/nrgyaltdicpt/Uo3I2FXEI8H6aFPBZq171/e2139f9575a4db6955dc2278dc08283c/latexmk-ol.mp4>" %}

手動コンパイルでは、別の LaTeX 実行（パス）が必要かどうかは通常は明らかですが、LaTeX コンパイルを自動化するのは多くの難しさを伴います。自動化ソリューションにおける重要な課題の1つは、 *どれだけの* LaTeX パス（コンパイル）が、データ依存関係を解決するために必要かを判断し、最終的に組版された文書が最新かつ完全であることを保証することです。もう1つの複雑さは、文書内容の一部を前処理するために実行すべき外部プログラムを正しく識別することです。たとえば、文献一覧を作成するために BibTeX/BibLaTeX を実行したり、 [MetaPost](https://tug.org/metapost.html) または [Asymptote](https://asymptote.sourceforge.io/).

## latexmkの紹介

コンパイルを自動化するための、よく確立されたパッケージの1つは [`latexmk`](https://ctan.org/pkg/latexmk?lang=en)、TeX Live に含まれている大きな Perl スクリプトで、Overleaf があなたの LaTeX プロジェクトをコンパイルするために使用しています。 `latexmk` 必要な回数だけ自動的に LaTeX の実行を起動し、文書内容の一部を処理するために必要な外部（補助）プログラムを実行します。

### latexmkのカスタマイズ

とはいえ `latexmk` は非常に多用途ですが、LaTeX のコンパイル環境はさまざまであり、文書の種類も非常に幅広いため、 `latexmk` が、考え得るあらゆる LaTeX 文書のニーズを完全に満たす自動化ソリューションを提供しようとするのは現実的ではありません。代わりに、 `latexmk` の動作は設定ファイルによってカスタマイズできます *が実装されている **Perl***:

* という、特定のコンピューティング環境/プラットフォームに対応する「システム全体」の設定ファイルと
* 文書固有の要件を処理するユーザーレベルの設定ファイル

この [`latexmkマニュアル`](http://mirrors.ctan.org/support/latexmk/latexmk.pdf) では、設定ファイルのインストールと使用法について詳しく説明しています。

## Overleaf の LatexMk ファイル

Overleaf の「システム全体」設定ファイルは Linux の `latexmk` の規則に従っています。ファイル名は `**LatexMk**` で、フォルダー `/usr/local/share/latexmk/`. **注**にあり、そのファイルは *より前に* ユーザーレベルの設定ファイルよりも先に読み込まれます。

ユーザーレベルの設定ファイルは `latexmkrc` という名前にし、Overleaf プロジェクトに追加して、Overleaf の LaTeX プロジェクト/文書の特定要件に対応するカスタムルールを提供する必要があります。

Overleaf の `LatexMk` ファイルには、Overleaf 固有の処理のためのコードに加え、用語集、命名規則、その他よく使われるパッケージのルールが含まれています。Overleaf の `LatexMk` ファイルは、TeX Live 内のパッケージやソフトウェアツールに加えられた変更や更新に対応するため、TeX Live 自体のリリースごとに多少異なる場合があります。

### LaTeX のコンパイルモードを変更する

既定では、Overleaf は latexmk に対して、私たち（Overleaf）が **エラーがあってもコンパイルを試みる**と呼ぶコンパイルモードを使うよう指示します。このモードでは、 [LaTeX のコンパイルエラー](/latex/ja/latexno/05-errors.md)エラーに遭遇しても LaTeX コンパイラは停止しません。出力が誤っていても、PDF が生成されることがあります。しばしば、コンパイルエラーが深刻すぎるか多すぎて LaTeX コンパイラが修正できず、それでも PDF を生成せずに「中断」してしまうことがあります。

最初のエラーで直ちにコンパイルを停止するように LaTeX のコンパイルモードを変更できます。ヘルプ記事 [最初のエラーで停止するコンパイルモードの使用](/latex/ja/narejjibsu/149-using-the-stop-on-first-error-compilation-mode.md) さらに情報を得ることができます。

### Overleaf の LatexMk ファイルのコピーにアクセスする方法

次のリンクを開くと、Overleaf の `LatexMk` ファイルを組版するプロジェクトが開かれ、プロジェクトの LaTeX コンパイラと TeX Live バージョンで使用されているものが分かるほか、ダウンロードも可能になります:

```latex
\documentclass[a4paper]{article}
\usepackage[margin=1cm]{geometry}
\usepackage{verbatim,shellesc}
\ShellEscape{cp /usr/local/share/latexmk/LatexMk ./LatexMk}
\begin{document}
\section*{このプロジェクトについて}
このプロジェクトでは、Overleaf が使用しているシステムの \texttt{LatexMk} 初期化（設定）ファイルにアクセスできます。\texttt{LatexMk} は Perl スクリプトで、プロジェクトで選択された \TeX{} Live のバージョンとコンパイラに応じて多少異なる場合があります。どの \texttt{LatexMk} が使われているかを 100\% 確実に知りたい場合は、このプロジェクトのコードをあなたのプロジェクトに追加し、コンパイルして \texttt{LatexMk} の一覧を組版し、出力ファイルの1つとしてダウンロードできるようにしてください。
\section*{\texttt{LatexMk} ファイルの一覧}
\verbatiminput{./LatexMk}
\end{document}
```

[このコードを Overleaf で開く。](https://www.overleaf.com/docs?engine=\&snip_name=Display+Overleaf+latexmkrc+file\&snip=%5Cdocumentclass%5Ba4paper%5D%7Barticle%7D%0A%5Cusepackage%5Bmargin%3D1cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%2Cshellesc%7D%0A%5CShellEscape%7Bcp+%2Fusr%2Flocal%2Fshare%2Flatexmk%2FLatexMk+.%2FLatexMk%7D%0A%5Cbegin%7Bdocument%7D%0A%5Csection%2A%7BAbout+this+project%7D%0AThis+project+provides+access+to+the+system+%5Ctexttt%7BLatexMk%7D+initialization+%28configuration%29+file+used+by+Overleaf.++%5Ctexttt%7BLatexMk%7D+is+a+Perl+script+which+may+vary+slightly+according+to+the+%5CTeX%7B%7D+Live+version+and+compiler+chosen+for+the+project.+If+you+need+to+be+100%5C%25+certain+which++%5Ctexttt%7BLatexMk%7D+is+being+used%2C+add+code+from+this+project+to+your+project+and+compile+to+typeset+a+listing+of+%5Ctexttt%7BLatexMk%7D+and+make+it+available+for+download+as+one+of+the+output+files.%0A%5Csection%2A%7BListing+the+%5Ctexttt%7BLatexMk%7D+file%7D%0A%5Cverbatiminput%7B.%2FLatexMk%7D%0A%5Cend%7Bdocument%7D)

上のプロジェクトをコンパイルすると、 `LatexMk` ファイルは **ログと出力ファイル** ボタンからダウンロードできます。次の短い動画クリップに示すとおりです:

{% embed url="<https://videos.ctfassets.net/nrgyaltdicpt/1re6AeMUF2EQnlZ8Cse5ke/ae6ee91fa7e2b2efa8ffb27ad8bab1a0/latexmkrc.mp4>" %}

### その他の注意とアドバイス

プロジェクトのコンパイルに使用される TeX Live のバージョンを設定または確認したい場合は、この [Overleaf ブログ記事](https://www.overleaf.com/blog/new-feature-select-your-tex-live-compiler-version#How-Switch) または次の図を参照してください:

![Overleaf の TeX Live バージョンの選択](/files/a7bf6b99425e8706d46de8ca268c526967689170)

latexmk を使って Overleaf プロジェクトをオフラインでビルドしたい場合、Overleaf のビルド手順が適用されるように Overleaf の LatexMk ファイルのコピーを使うとよいでしょう。なお、Overleaf のジョブ名は出力先に設定されています。

Overleaf は latexmk の `-cd` コマンドラインフラグを使ってプロジェクトをコンパイルし、常にプロジェクトのルートディレクトリからコンパイルを実行します。なお、いくつかの `latexmk` オプションは Overleaf と互換性がありません。特に、 `$preview_continuous_mode` または `$output_dir` オプションを設定すると、Overleaf 上のプレビューが壊れる可能性があります。

についての詳細は `latexmkrc` ファイルについての記事を読むには [Overleaf で latexmkrc を使う方法](/latex/ja/xiang-xi-ji-shi/28-how-to-use-latexmkrc-with-overleaf.md) を参照してください。そこには、親切な Overleaf TeXperts からの役立つヒントとコツがあります。

## Overleaf の LatexMk ファイルの一覧（2023）

見やすいように、次の一覧では TeX Live 2023 で使用されている Overleaf の `LatexMk` ファイルを示しています。最新バージョンにアクセスするには上のリンクを使ってください。

```perl
# 設定
$xdvipdfmx = "xdvipdfmx -z 6 -i dvipdfmx-unsafe.cfg -o %D %O %S";

# pstricks の透明度を許可するための回避策 (https://github.com/overleaf/issues/issues/3449)
$dvipdf = "dvipdf -dNOSAFER -dALLOWPSTRANSPARENCY %O %S %D";

###############################
# pdf ファイルの後処理 #
###############################

$compiling_cmd = "internal overleaf_pre_process %T %D";
$success_cmd = "internal overleaf_post_process %T %D";
$failure_cmd = $success_cmd;

# -gt オプションと同等。latexmk が再コンパイルをスキップするのを防ぐために使用
# output.log と output.pdf の
$go_mode = 3;

# -bibtex オプションと同等。bbl ファイルが
# 期限切れのときに無条件で bibtex を実行する。
$bibtex_use = 2;

my $ORIG_PDF_AGE;

sub overleaf_pre_process {
    my $source_file = $_[0];
    my $output_file = $_[1];

    # 既存の pdf があれば、その経過時間を取得
    $ORIG_PDF_AGE = -M $output_file
}

sub overleaf_post_process {
    my $source_file = $_[0];
    my $output_file = $_[1];
    my $source_without_ext = $source_file =~ s/\.tex$//r;
    my $output_without_ext = $output_file =~ s/\.pdf$//r;

    # knitr の concordance ファイルを探す
    my $concordance_file = "${source_without_ext}-concordance.tex";
    if (-e $concordance_file) {
        print "knitr 用に synctex ファイルをパッチしています...\n";
        system("patchSynctex.R", $source_without_ext, $output_without_ext);
    }

    # pdf ファイルが存在しないか更新されていない場合は早期に戻る
    my $NEW_PDF_AGE = -M $output_file;
    return if !defined($NEW_PDF_AGE);
    return if defined($ORIG_PDF_AGE) && $NEW_PDF_AGE == $ORIG_PDF_AGE;

    # qpdf の場所を見つける
    $qpdf //= "/usr/bin/qpdf";
    $qpdf = $ENV{QPDF} if defined($ENV{QPDF}) && -x $ENV{QPDF};
    return if ! -x $qpdf;
    $qpdf_opts //= "--linearize --newline-before-endstream";
    $qpdf_opts = $ENV{QPDF_OPTS} if defined($ENV{QPDF_OPTS});

    # qpdf を実行
    my $optimised_file = "${output_file}.opt";
    system($qpdf, split(' ', $qpdf_opts), $output_file, $optimised_file);
    $qpdf_exit_code = ($? >> 8);
    print "qpdf の終了コード=$qpdf_exit_code\n";

    # qpdf が成功した場合は出力ファイルを置き換える
    # qpdf は成功で 0、警告で 3 を返す（出力 PDF はそれでも作成される）
    return if !($qpdf_exit_code == 0 || $qpdf_exit_code == 3);
    print "最適化済みファイルを $output_file に名前変更しています\n";
    rename($optimised_file, $output_file);

    print "$output_file の xref テーブルを抽出しています\n";
    my $xref_file = "${output_file}xref";
    system("$qpdf --show-xref ${output_file} > ${xref_file}");
    $qpdf_xref_exit_code = ($? >> 8);
    print "qpdf --show-xref の終了コード=$qpdf_xref_exit_code\n";
}

##############
# 用語集 #
##############
add_cus_dep( 'glo', 'gls', 0, 'glo2gls' );
add_cus_dep( 'acn', 'acr', 0, 'glo2gls');  # Overleaf v1 から
sub glo2gls {
    system("makeglossaries $_[0]");
}

#############
# makeindex #
#############
@ist = glob("*.ist");
if (scalar(@ist) > 0) {
    $makeindex = "makeindex -s $ist[0] %O -o %D %S";
}

################
# 命名規則 #
################
add_cus_dep("nlo", "nls", 0, "nlo2nls");
sub nlo2nls {
        system("makeindex $_[0].nlo -s nomencl.ist -o $_[0].nls -t $_[0].nlg");
}

#########
# knitr #
#########
add_cus_dep( 'Rtex', 'tex', 0, 'do_knitr');
add_cus_dep( 'Rnw', 'tex', 0, 'do_knitr');
sub do_knitr {
    Run_subst(qq{Rscript -e '
        library("knitr");
        opts_knit\$set(concordance=T);
        knitr::knit(%S, output=%D);
        '}
    );
}

##########
# feynmf #
##########
push(@file_not_found, '^feynmf: Files .* and (.*) not found:$');
add_cus_dep("mf", "tfm", 0, "mf_to_tfm");
sub mf_to_tfm { system("mf '\\mode:=laserjet; input $_[0]'"); }

push(@file_not_found, '^feynmf: Label file (.*) not found:$');
add_cus_dep("mf", "t1", 0, "mf_to_label1");
sub mf_to_label1 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t1"); }
add_cus_dep("mf", "t2", 0, "mf_to_label2");
sub mf_to_label2 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t2"); }
add_cus_dep("mf", "t3", 0, "mf_to_label3");
sub mf_to_label3 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t3"); }
add_cus_dep("mf", "t4", 0, "mf_to_label4");
sub mf_to_label4 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t4"); }
add_cus_dep("mf", "t5", 0, "mf_to_label5");
sub mf_to_label5 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t5"); }
add_cus_dep("mf", "t6", 0, "mf_to_label6");
sub mf_to_label6 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t6"); }
add_cus_dep("mf", "t7", 0, "mf_to_label7");
sub mf_to_label7 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t7"); }
add_cus_dep("mf", "t8", 0, "mf_to_label8");
sub mf_to_label8 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t8"); }
add_cus_dep("mf", "t9", 0, "mf_to_label9");
sub mf_to_label9 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t9"); }

##########
# feynmp #
##########
push(@file_not_found, '^dvipdf: 図ファイル (.*) が見つかりませんでした。続行します。$');
add_cus_dep("mp", "1", 0, "mp_to_eps");
sub mp_to_eps {
    system("mpost $_[0]");
    return 0;
}

#############
# asymptote #
#############

sub asy {return system("asy \"$_[0]\"");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");

#############
# metapost  #  # Overleaf v1 から
#############
add_cus_dep('mp', '1', 0, 'mpost');
sub mpost {
    my $file = $_[0];
    my ($name, $path) = fileparse($file);
    pushd($path);
    my $return = system "mpost $name";
    popd();
    return $return;
}

##########
# chktex #
##########
output.chktex が存在する場合は unlink する
if (defined $ENV{'CHKTEX_OPTIONS'}) {
    use File::Basename;
    use Cwd;

    # メインファイルを特定する
    my $target = $ARGV[-1];
    my $file = basename($target);

    if ($file =~ /\.tex$/) {
        # 限定された範囲でディレクトリを変更する
        my $orig_dir = cwd();
        my $subdir = dirname($target);
        chdir($subdir);
        # メインファイルに対して chktex を実行する
        $status = system("/usr/local/bin/run-chktex.sh", $orig_dir, $file);
        # 元のディレクトリに戻る
        chdir($orig_dir);

        # VALIDATE モードでは、chktex 実行後に常に終了する
        # それ以外では、EXIT_ON_ERROR が設定されている場合に終了する

        if ($ENV{'CHKTEX_EXIT_ON_ERROR'} || $ENV{'CHKTEX_VALIDATE'}) {
            # chktex では、終了ステータス経由でエラー情報にアクセスできない
            # そのため、出力を確認する
            open(my $fh, "<", "output.chktex");
            my $errors = 0;
            {
                local $/ = "\n";
                while(<$fh>) {
                    if (/^\S+:\d+:\d+: Error:/) {
                        $errors++;
                        print;
                    }
                }
            }
            close($fh);
            exit(1) if $errors > 0;
            exit(0) if $ENV{'CHKTEX_VALIDATE'};
        }
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/ja/narejjibsu/064-how-does-overleaf-compile-my-project.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
