본문 바로가기
프로그래밍/Unity

Unity의 Scripting Backend, Mono와 IL2CPP 빌드 차이

by argentdarae 2025. 3. 24.
반응형

개요

Unity Scripting Backend 빌드 설정 중 Mono와 IL2CPP에 대해 설명하고, 차이점을 정리한 글이다

 

Mono 빌드

출처: Unity Doc
출처: https://www.youtube.com/watch?v=-9X965jXrn8

 

Unity는 C# 스크립트를 Roslyn 컴파일러로 컴파일하여 IL 형태의 DLL로 저장한다

빌드 결과물은 IL로 구성된 .NET 어셈블리 파일이며, 플랫폼에서 직접 실행되는 네이티브 바이너리는 아니다

 

빌드 시간은 IL2CPP에 비해 상대적으로 빠르다

이는 프로그램 실행 시 바이너리 코드로 변환되기 때문인데, 코드를 IL 까지만 변환시키면 되기 때문이다

 

프로그램 실행 후엔 Mono Runtime이 동작한다. Mono Runtime은 JIT 방식으로 동작한다. 필요한 시점에 IL 코드를 머신 코드로 변환하여 실행하는 것이다

예를 들어, Update() 함수가 처음 호출될 때 그 함수에 해당하는 IL이 JIT 컴파일 되어 Native Code(실행 코드)로 변환된다

JIT 변환된 코드는 해당 런타임 세션 내에서 메서드 단위로 캐시되며, 이후 동일 메서드 호출 시 재사용된다.

 

유니티 에디터 환경도 Mono 기반이며, 스크립트 실행 시 JIT 방식을 사용한다
이는 빠른 반복 테스트와 디버깅을 가능하게 해준다

 

IL2CPP 빌드

출처: Unity Doc
출처: https://www.youtube.com/watch?v=-9X965jXrn8

 

Unity는 C# 스크립트를 Roslyn 컴파일러로 컴파일하여 IL 형태의 DLL로 만든 뒤

 

이후 Unity가 개발한 IL2CPP.exe 컴파일러가 실행되어 IL to C++ 이름처럼 IL을 C++로 변환하고 플랫폼에 맞는 네이티브 바이너리(실행 파일)로 빌드한다

 

이 빌드 과정은 Mono 빌드보다 상대적으로 오래 걸린다. IL이 한 번 더 C++ 코드로 변환된 후 플랫폼에 맞게 컴파일되기 때문이다

JIT 방식에서 런타임에 수행되는 컴파일 과정을, IL2CPP는 컴파일 타임에 미리 처리(AOT)함으로써 실행 시 오버헤드를 줄인다

 

프로그램 실행 후엔 이미 AOT로 컴파일 되어있기 때문에, 별도의 코드 변환 없이 바로 실행된다

 

Mono와 IL2CPP 차이점 정리

항목 Mono (JIT) IL2CPP (AOT)
빌드 과정 C# => IL C# => IL => C++ => Native Binary
실행 방식 런타임 중 IL을 JIT 컴파일하여 실행 이미 컴파일된 네이티브 바이너리 직접 실행
빌드 속도 빠름 느림 (변환 + AOT 컴파일 추가)
실행 성능 중간 (초기 JIT 비용 존재) 높음 (최적화된 네이티브 코드)
플랫폼 호환성 제한 있음 매우 넓음

 


Reference

[유니티 TIPS] 알고 있으면 쓸데 있는 IL2CPP, Mono, AOT, JIT 개념 파헤치기 - Youtube

JIT 컴파일 - Wikipedia

AOT 컴파일 - Wikipedia

Mono 개요 - Unity Doc

IL2CPP 개요 - Unity Doc

An introduction to IL2CPP internals - Unity Tech Blog

C# 컴파일러 - Unity Doc

Roslyn (compiler) - Wikipedia

Roslyn - Github