# IL2CPP 개요

> IL2CPP is Unity's ahead-of-time (AOT) pipeline that converts C# intermediate language (IL) to C++, then compiles to native code. It's required on several platforms where Mono and JIT are not supported.

**IL2CPP**(C++로 변환하기 위한 중간 언어) 스크립팅 백엔드는 Mono 백엔드의 대안입니다. IL2CPP는 더욱 다양한 플랫폼에서 애플리케이션에 대해 더 나은 지원을 제공합니다. IL2CPP 백엔드는 MSIL(Microsoft 중간 언어) 코드(예: 스크립트 내의 C# 코드)를 C++ 코드로 전환한 뒤 C++ 코드를 사용하여 선택한 플랫폼에 대한 네이티브 바이너리 파일(예: .exe, .apk, .xap)을 생성합니다.

Unity가 네이티브 바이너리를 빌드할 때 특히 타겟 플랫폼에 대해 코드를 컴파일하는 이런 유형의 컴파일을 AOT(Ahead-Of-Time) 컴파일이라고 부릅니다. [Mono 백엔드](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/mono.md)는 JIT(just-in-time) 컴파일이라는 기법을 통해 런타임 시 코드를 컴파일합니다.

이 페이지에서는 다음의 내용을 다룹니다.

* [IL2CPP를 사용한 프로젝트 빌드](#BuildingProject)
* [IL2CPP 작동 방식](#HowItWorks)
* [IL2CPP 빌드 시간 최적화](#OptimizingBuildTimes)
* [IL2CppSetOption을 사용하여 런타임 체크 활성화](#EnablingRuntimeChecksUsingIl2CppSetOption)

일부 플랫폼은 AOT 컴파일을 지원하지 않으므로 IL2CPP 백엔드는 모든 플랫폼에서 작동하지는 않습니다. 다른 플랫폼은 AOT 및 IL2CPP를 지원하지만 JIT 컴파일을 허용하지 않으므로 Mono 백엔드를 지원할 수 없습니다. 플랫폼이 두 백엔드를 모두 지원할 수 있는 경우 Mono가 기본값입니다. 자세한 내용은 [스크립팅 제한 사항](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/restrictions.md)을 참조하십시오.

IL2CPP는 다양한 플랫폼에서 성능을 향상시킬 수 있지만, 빌드된 애플리케이션에 기계어 코드를 포함해야 하기 때문에 빌드 시간과 최종 빌드된 애플리케이션의 크기가 모두 증가합니다. 자세한 내용은 IL2CPP 작동 방식과 블로그에서 시리즈로 다룬 [IL2CPP 원리 소개](https://blog.unity.com/technology/an-introduction-to-ilcpp-internals)를 참조하십시오.

IL2CPP는 Mono 스크립팅 백엔드와 동일한 방식으로 관리되는 코드의 디버깅을 지원합니다. 자세한 내용은 [Unity에서 C# 코드 디버깅](/engine/6000.0/manual/scripting/debugging-and-diagnostics/managed-code-debugging.md)을 참조하십시오.

## IL2CPP를 사용한 프로젝트 빌드

IL2CPP를 사용하여 프로젝트를 빌드하려면 Unity 설치에 백엔드를 설치해야 합니다. Unity 버전을 처음 설치할 경우, 선택적 모듈로 IL2CPP를 선택하거나 Unity Hub를 통해 기존 설치에 IL2CPP 지원을 추가할 수 있습니다. 자세한 내용은 [Unity Hub 설치](https://docs.unity3d.com/hub/manual/index.html) 및 [Unity 에디터에 모듈 추가](https://docs.unity3d.com/hub/manual/AddModules.html)를 참조하십시오.

또한 IL2CPP로 C++ 코드를 생성하려면 타겟 플랫폼의 특정한 시스템 환경이 필요합니다. 즉 특정 플랫폼에서 IL2CPP를 사용하려면 해당 플랫폼에서 애플리케이션을 빌드해야 한다는 뜻입니다. 예를 들어 IL2CPP를 사용할 때 MacOS를 빌드 타겟으로 하려면 MacOS를 사용하는 컴퓨터에서 애플리케이션을 빌드해야 합니다. 개별 플랫폼에 대한 IL2CPP 요구 사항을 포함하는 데스크톱 플랫폼에 대한 상세 시스템 요구 사항은 [Unity용 시스템 요구 사항](https://docs.unity3d.com/Manual/system-requirements.html#desktop)의 데스크톱 섹션을 참조하십시오.

Unity가 사용하는 스크립팅 백엔드를 변경하여 다음 두 가지 방법 중 하나로 애플리케이션을 빌드할 수 있습니다.

* 에디터의 **Player Settings** 메뉴를 사용하는 방법입니다. **Player Settings** 메뉴를 통해 스크립팅 백엔드를 변경하려면 다음 단계를 수행해야 합니다.

  1. **Edit** > **Project Settings**로 이동합니다.
  2. **Player Settings** 버튼을 클릭하여 [**인스펙터**](/engine/6000.0/manual/unity-editor/using-the-editor/using-the-inspector.md)에서 현재 플랫폼에 대한 [**Player**](/engine/6000.0/manual/unity-editor/editor-features/comp-manager-group/class-player-settings.md) 설정을 엽니다.
  3. **Other Settings** 하위 메뉴 아래의 **Configuration** 섹션으로 이동합니다.
  4. **Scripting Backend** 드롭다운 메뉴를 클릭한 후 **IL2CPP**를 선택합니다.

  **Build Profiles** 창에서 **Player Settings** 메뉴를 열 수도 있습니다. **File** > **Build Profiles**로 이동하여 **Player Settings** 탭을 클릭하면 됩니다.

* 에디터 스크립팅 API를 사용하는 방법입니다. [PlayerSettings.SetSkriptingBackend](/engine/6000.0/script-reference/unity-editor/player-settings/set-scripting-backend.md) 프로퍼티를 사용하여 Unity가 사용하는 스크립팅 백엔드를 변경합니다.


**Player 설정의 Configuration 섹션:**
![](/api/media?file=/engine/6000.0/media/images/IL2CPP-build-settings.png)

빌드 프로세스를 시작하려면 **Build Profiles** 창을 열고 **Build** 버튼을 클릭합니다. 그러면 Unity는 C# 코드와 어셈블리를 C++로 전환한 후 마지막으로 타겟 플랫폼에 바이너리 파일을 생성합니다.

## IL2CPP 작동 방식

IL2CPP를 사용하여 빌드를 시작하면 Unity는 자동으로 다음의 단계를 수행합니다.

1. Roslyn C# 컴파일러가 애플리케이션의 C# 코드와 다른 필수 패키지 코드를 .NET DLLs(관리되는 어셈블리)로 컴파일합니다.
2. Unity가 관리되는 [바이트코드 스트리핑](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/managed-code-stripping.md)을 적용합니다. 이 단계에서는 빌드된 애플리케이션의 크기를 크게 줄일 수 있습니다.
3. IL2CPP 백엔드가 모든 관리되는 어셈블리를 표준 C++ 코드로 전환합니다.
4. C++ 컴파일러는 생성된 C++ 코드와 IL2CPP의 런타임 부분을 네이티브 플랫폼 컴파일러로 컴파일합니다.
5. Unity는 대상 플랫폼에 따라 실행 가능한 파일이나 DLL을 생성합니다.

IL2CPP와 Mono 모두 스크립트의 속성을 통해 제어할 수 있는 몇 가지 유용한 옵션을 제공합니다. 자세한 내용은 [플랫폼에 따른 컴파일](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/platform-dependent-compilation.md)을 참조하십시오.

Unity는 IL2CPP를 사용하여 특정 플랫폼에 대한 코드를 사전에 컴파일할 수 있습니다. 이 프로세스가 끝날 때 Unity가 생성하는 바이너리 파일에는 타겟 플랫폼용 필수 기계어 코드가 이미 포함되어 있으나, Mono는 실행 중 런타임 시에 이 기계어 코드를 컴파일해야 합니다. AOT 컴파일은 빌드 시간을 늘리지만, 타겟 플랫폼과의 호환성을 높이고 성능을 개선할 수 있습니다.

두 스크립팅 백엔드에는 타게팅하려는 각 플랫폼에 대한 새로운 빌드가 필요합니다. 예를 들어 Android와 iOS 플랫폼 둘 다를 지원하려면 애플리케이션을 두 번 빌드하고 바이너리 파일도 두 개 생성해야 합니다.

어셈블리 스트리핑 단계는 최종 바이너리 크기를 줄이는 데 도움이 됩니다. Unity는 최종 빌드된 애플리케이션이 사용하지 않는 바이트코드를 제거합니다.

## IL2CPP 빌드 시간 최적화

IL2CPP를 사용할 때 프로젝트 빌드 시간은 Mono를 사용할 때보다 훨씬 길어질 수 있습니다. 하지만 몇 가지 방법을 사용해 빌드 시간을 단축할 수 있습니다.

**멀웨어 차단 소프트웨어 검사에서 프로젝트 제외**

프로젝트를 빌드하기 전에 멀웨어 차단 소프트웨어 검사에서 Unity 프로젝트 폴더와 타겟 빌드 폴더를 제외할 수 있습니다.

**SSD(Solid State Drive)에 프로젝트와 타겟 빌드 폴더 저장**

SSD(솔리드 스테이트 드라이브)는 기존 HDD(하드 디스크 드라이브)에 비해 읽기/쓰기 속도가 빠릅니다. IL 코드를 C++로 전환하고 컴파일하려면 수많은 읽기/쓰기 작업이 필요하기 때문에 저장 장치가 빠를수록 처리 속도도 빨라집니다.

**Player 설정에서 IL2CPP 코드 생성 옵션 변경**

IL2CPP가 코드를 생성하는 방법을 변경하려면 [Player Settings](/engine/6000.0/manual/unity-editor/editor-features/comp-manager-group/class-player-settings.md)를 열어 IL2CPP 코드 생성 옵션을 설정합니다. 기본적으로 Faster runtime 옵션이 활성화되며 이는 런타임 시 IL2CPP의 영향을 줄여주는 기계어 코드를 더 많이 생성합니다. 빌드 시간을 줄이려면 이 옵션을 Faster (smaller) builds로 설정하면 됩니다. 이 메서드는 바이너리 실행 파일에 기계어 코드를 더 적게 생성하고 포함하므로 런타임 시 성능이 저하될 수 있지만, 빌드 시간과 바이너리 크기를 크게 줄여줍니다.

## Il2CppSetOption을 사용하여 런타임 체크 활성화

IL2CPP 스크립팅 백엔드를 사용하면 **il2cpp.exe**가 C++ 코드를 생성하는 방식을 제어할 수 있습니다. **Il2CppSetOption** 속성을 사용하여 다음 런타임 체크를 활성화하거나 비활성화할 수 있습니다.

| **프로퍼티:**                 | **설명:**                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | **기본값:** |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| **Null checks**           | 이 옵션을 활성화하면 IL2CPP가 생성하는 C++ 코드가 null 체크가 포함되며 필요한 경우 관리되는 NullReferenceException 예외가 발생합니다. 이 옵션을 비활성화하면 IL2CPP는 생성된 C++ 코드에 null 체크를 내보내지 않습니다. 일부 프로젝트에서는 이 옵션을 비활성화하면 런타임 성능이 향상될 수도 있습니다.이 설정을 비활성화하면 Unity는 생성된 코드의 null 값에 액세스하려는 시도를 방지하지 않으므로 잘못된 동작이 발생할 수 있습니다. 애플리케이션이 null 값을 역참조하면 곧바로 충돌이 발생할 수 있습니다. Unity에서는 이 옵션을 비활성화하지 않는 것이 좋습니다.                                                                                                                            | 활성화      |
| **Array bounds checks**   | 이 옵션을 활성화하면 IL2CPP가 생성하는 C++ 코드에 배열 바운드 체크가 포함되며 필요한 경우 관리되는 IndexOutOfRangeException 예외가 발생합니다. 이 옵션을 비활성화하면 IL2CPP는 생성된 C++ 코드에 배열 바운드 체크를 내보내지 않습니다.일부 프로젝트에서는 이 옵션을 비활성화하면 런타임 성능이 향상될 수도 있습니다. 하지만 이 옵션을 비활성화하면 Unity는 생성된 코드의 유효하지 않은 인덱스를 가진 배열에 액세스하려는 시도를 차단하지 않으므로 임의의 메모리 위치에서 읽거나 쓰는 등의 잘못된 동작을 일으킬 수 있습니다. 대부분의 경우 이러한 메모리 액세스가 발생하더라도 즉각적인 부작용이 나타나지 않을 수 있으며 명확한 경고도 없이 애플리케이션의 상태를 손상시킬 수 있습니다. 이 경우 오류 디버깅이 매우 어려워질 수 있습니다. Unity에서는 이 옵션을 활성화 상태로 유지하는 것이 좋습니다. | 활성화      |
| **Divide by zero checks** | 이 옵션을 활성화하면 IL2CPP가 생성하는 C++ 코드에는 정수 나눗셈에 대한 0으로 나누기 체크가 포함되며 필요에 따라 관리되는 DivideByZeroException 예외를 발생시킵니다. 이 옵션을 비활성화하면 IL2CPP는 생성된 C++ 코드의 정수 나눗셈에 대하여 0으로 나누기 체크를 포함시키지 않습니다.이러한 체크는 런타임 시 성능에 영향을 미칩니다. 이 옵션은 0으로 나누기 체크를 실행해야 하는 경우에만 활성화해야 하며 그 외의 경우에는 비활성화 상태로 둬야 합니다.                                                                                                                                                                                                    | Disabled |

**Il2CppSetOption** 속성을 사용하는 방법은 다음과 같습니다.

1. Unity 버전이 설치된 디렉토리에서 Windows에서는 **Data\il2cpp** 디렉토리로 이동하고 OS X에서는 **Contents/Frameworks/il2cpp** 디렉토리로 이동합니다.
2. **Il2CppSetOptionAttribute.cs** 소스 파일을 찾습니다.
3. 해당 소스 파일을 프로젝트의 **Assets** 디렉토리로 복사합니다.

**Il2CppSetOption** 속성을 사용하는 방법은 아래의 예제에 설명되어 있습니다.

```lang-C#
[Il2CppSetOption(Option.NullChecks, false)]
public static string MethodWithNullChecksDisabled()
{
    var tmp = new object();
    return tmp.ToString();
}
```

어셈블리, 유형, 메서드, 프로퍼티에 **Il2CppSetOption** 속성을 적용할 수 있습니다. Unity는 가장 로컬 범위의 속성을 사용합니다.

```lang-C#
[Il2CppSetOption(Option.NullChecks, false)]
public class TypeWithNullChecksDisabled
{
    public static string AnyMethod()
    {
        // Unity doesn’t perform null checks in this method.
        var tmp = new object();
        return tmp.ToString();
    }

    [Il2CppSetOption(Option.NullChecks, true)]
    public static string MethodWithNullChecksEnabled()
    {
        // Unity performs null checks in this method.
        var tmp = new object();
        return tmp.ToString();
    }
}

public class SomeType
{
    [Il2CppSetOption(Option.NullChecks, false)]
    public string PropertyWithNullChecksDisabled
    {
        get
        {
            // Unity doesn’t perform null checks here.
            var tmp = new object();
            return tmp.ToString();
        }
        set
        {
            // Unity doesn’t perform null checks here.
            value.ToString();
        }
    }

    public string PropertyWithNullChecksDisabledOnGetterOnly
    {
        [Il2CppSetOption(Option.NullChecks, false)]
        get
        {
            // Unity doesn’t perform null checks here.
            var tmp = new object();
            return tmp.ToString();
        }
        set
        {
            // Unity performs null checks here.
            value.ToString();
        }
    }
}
```

## 추가 리소스

* [IL2CPP 추가 인수 처리](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/il2cpp/handling-il2cpp-additional-args.md)
* [Linux IL2CPP 크로스 컴파일러](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/il2cpp/linux-il2cpp-crosscompiler.md)
* [Windows 런타임 지원](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/il2cpp/il2cpp-windows-runtime-support.md)
* [매니지드 스택 추적](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends/il2cpp/il2cpp-managed-stack-traces.md)
