> 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/ko/knowledge-base/064-how-does-overleaf-compile-my-project.md).

# Overleaf는 내 프로젝트를 어떻게 컴파일하나요?

## LaTeX 컴파일 자동화

목차, 그림 목록, 상호 참조, 용어집, 색인, 참고문헌 인용과 같은 기능을 지원하기 위해 LaTeX는 다중 패스 조판 과정을 사용합니다. 한 패스(컴파일)에서 생성된 데이터는 파일에 기록되어, 필요한 후속 패스의 입력으로 사용됩니다. 다음 동영상은 Overleaf 프로젝트에서 “Recompile” 버튼을 클릭할 때마다 어떤 일이 일어나는지 보여줍니다:

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

수동 컴파일을 수행할 때는 또 다른 LaTeX 실행(패스)이 필요한지 보통 분명하지만, LaTeX 컴파일을 자동화하는 데에는 여러 어려움이 있습니다. 자동화 솔루션의 핵심 과제는 *얼마나 많은* LaTeX 패스(컴파일)가 데이터 의존성을 해결하는 데 필요한지, 그리고 최종 조판 문서가 최신 상태이고 완전하도록 보장하는 것입니다. 또 다른 복잡성은 BibTeX/BibLaTeX를 실행해 참고문헌 목록을 생성하거나 다음과 같은 더 전문적인 그래픽 애플리케이션을 실행하는 것처럼 문서 내용의 일부를 전처리하기 위해 실행해야 하는 외부 프로그램을 정확히 식별하는 것입니다. [MetaPost](https://tug.org/metapost.html) 또는 [Asymptote](https://asymptote.sourceforge.io/).

## latexmk 소개

컴파일 자동화를 위한 잘 확립된 패키지 중 하나는 [`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의 “시스템 전역” 구성 파일은 `latexmk` 관례를 따릅니다(리눅스의 경우). 이름은 `**LatexMk**` 이며 폴더 `/usr/local/share/latexmk/`. **참고**에 위치합니다: 이 파일은 *이전의* 모든 사용자 수준 구성 파일보다 먼저 읽힙니다.

사용자 수준 구성 파일은 이름이 `latexmkrc` 이어야 하며, Overleaf LaTeX 프로젝트/문서의 특정 요구를 다루는 사용자 정의 규칙을 제공하기 위해 Overleaf 프로젝트에 추가되어야 합니다.

Overleaf의 `LatexMk` 파일에는 Overleaf 전용 처리용 코드와 함께 용어집, 용어 목록, 기타 흔히 사용되는 패키지를 위한 규칙이 들어 있습니다. Overleaf의 `LatexMk` 파일은 TeX Live 자체 내의 패키지 및 소프트웨어 도구에 대한 변경과 업데이트를 수용하기 위해 TeX Live 릴리스 간에 약간씩 달라질 수 있습니다.

### LaTeX의 컴파일 모드 변경하기

기본적으로 Overleaf는 latexmk가 우리가(Overleaf가) **오류가 있어도 컴파일 시도**라고 부르는 컴파일 모드를 사용하도록 지시합니다. 이 컴파일 모드에서는 LaTeX 컴파일러가 [LaTeX 컴파일 오류](/latex/ko/latex/05-errors.md)를 만나도 멈추지 않습니다. PDF가 생성될 수 있지만, 잘못된 출력이 포함되어 있을 수 있습니다. 종종 컴파일 오류가 너무 심각하거나 너무 많아서 LaTeX 컴파일러가 수정할 수 없으므로, PDF를 생성하지 못한 채 “중단”할 수도 있습니다.

첫 번째 오류를 만나자마자 즉시 컴파일이 중지되도록 LaTeX 컴파일 모드를 변경할 수 있습니다. 도움말 문서 [첫 번째 오류에서 중지(Stop on First Error) 컴파일 모드 사용하기](/latex/ko/knowledge-base/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}는 프로젝트에 선택된 \TeX{} Live 버전에 따라, 그리고 컴파일러에 따라 약간 달라질 수 있는 Perl 스크립트입니다. 어떤 \texttt{LatexMk}가 사용되는지 100\% 확실히 알아야 한다면, 이 프로젝트의 코드를 자신의 프로젝트에 추가하고 컴파일하여 \texttt{LatexMk}의 목록을 조판한 다음 출력 파일 중 하나로 다운로드할 수 있게 하세요.
\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/ac0509909439b3c69ea13243d058175f1f5b6021)

latexmk를 사용해 Overleaf 프로젝트를 오프라인에서 빌드하려면, Overleaf의 빌드 프로세스가 적용되도록 Overleaf의 LatexMk 파일 사본을 사용하는 것이 좋습니다. 참고로 Overleaf의 작업 이름(job name)은 output으로 설정됩니다.

Overleaf는 latexmk의 `-cd` 명령줄 플래그를 사용해 프로젝트를 컴파일하며, 컴파일은 항상 프로젝트의 루트 디렉터리에서 실행됩니다. 일부 `latexmk` 옵션은 Overleaf와 호환되지 않습니다. 특히 `$preview_continuous_mode` 또는 `$output_dir` 옵션을 설정하면 Overleaf의 미리보기가 깨질 수 있습니다.

에 대한 더 많은 정보는 `latexmkrc` 파일을 읽는 방법에 관한 문서 [How to use latexmkrc with Overleaf](/latex/ko/in-depth-articles/28-how-to-use-latexmkrc-with-overleaf.md) 를 참고하세요. 여기에는 친절한 Overleaf TeXpert들의 유용한 팁과 요령이 들어 있습니다.

## 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) {
        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'가 파일이면 'output.chktex'를 삭제
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);
        # main 파일에 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);
            $errors > 0이면 exit(1)
            CHKTEX_VALIDATE가 설정되어 있으면 exit(0)
        }
    }
}
```


---

# 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/ko/knowledge-base/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.
