Unity 빌드 프로세스는 Unity linker라는 툴을 사용하여 관리되는 코드를 스트리핑합니다. Unity linker는 Unity와 함께 사용할 수 있도록 커스터마이즈된 IL Linker 버전입니다. Unity linker의 커스텀 Unity 엔진별 부분은 공개적으로 제공되지 않습니다.
Unity linker는 관리되는 코드 스트리핑과 엔진 코드 스트리핑 프로세스의 일부를 담당하며 이는 미사용 엔진 코드를 제거하는__ IL2CPP__Unity에서 개발한 스크립팅 백엔드로, 여러 플랫폼용 프로젝트를 빌드할 때 Mono 대신 사용할 수 있습니다. 자세한 정보
See in Glossary 스크립트 백엔드를 통해 사용할 수 있는 별도의 프로세스입니다. 자세한 내용은 PlayerSettings.StripEngineCode를 참조하십시오.
Unity linker는 프로젝트의 모든 어셈블리를 분석합니다. 먼저 루트 유형, 메서드, 프로퍼티, 필드를 마킹합니다. 예를 들어 씬의 게임 오브젝트에 추가하는 MonoBehaviour 파생 클래스는 루트 유형입니다. \
그러면 Unity linker는 식별할 루트를 분석하고 이러한 루트가 종속되는 관리되는 코드를 마킹합니다. 정적 분석이 완료되면 애플리케이션 코드를 통한 모든 실행 경로에서 마킹되지 않은 남은 코드에 도달할 수 없으며 Unity linker는 해당 코드를 어셈블리에서 삭제합니다.
Unity 에디터는 Unity 프로젝트의 씬에서 사용되는 유형을 포함하는 어셈블리의 리스트를 생성하고 이 리스트를 Unity linker에 전달합니다. 그런 다음 Unity linker는 해당 어셈블리, 해당 어셈블리의 레퍼런스, link.xml 파일에서 선언된 어셈블리, AlwaysLinkAssembly 속성이 있는 어셈블리를 처리합니다. 일반적으로 Unity linker는 이러한 카테고리 중 하나에 속하지 않는 프로젝트에 포함된 어셈블리를 처리하지 않으며 플레이어 빌드에서 제외합니다.
Unity linker가 어셈블리를 처리할 때마다 어셈블리 분류, 어셈블리가 씬에서 사용되는 유형을 포함하는지 여부, 해당 빌드에 대해 선택한 관리되되는 스트리핑 레벨에 따라 일련의 규칙을 준수합니다.
이러한 규칙에서 어셈블리는 다음과 같이 분류됩니다.
Unity에서 프로젝트를 빌드할 때 빌드 프로세스는 C# 코드를 CIL(일반 중간 언어)이라는 .NET 바이트코드 포맷으로 컴파일합니다. Unity는 이 CIL 바이트 코드를 어셈블리라는 파일로 패키징합니다. 프로젝트에서 사용하는 플러그인의 .NET 프레임워크 라이브러리와 C# 라이브러리는 CIL 바이트코드의 어셈블리로 사전 패키징됩니다.
Unity linker는 정적 분석을 수행할 때 일련의 규칙을 따라 Unity linker가 빌드에 필요하다고 표시하는 CIL 바이트코드의 일부를 결정합니다. 루트 마킹 규칙에는 Unity linker가 빌드의 최상위 레벨 어셈블리를 식별하고 보존하는 방식을 결정합니다. 종속성 마킹 규칙에는 Unity linker가 루트 어셈블리가 의존하는 모든 코드를 식별하고 보존하는 방식을 결정합니다.
Managed Stripping Level 프로퍼티는 Unity linker가 사용하는 규칙 세트를 변경합니다. 다음 섹션에서는 Managed Stripping Level 프로퍼티에 대해 가능한 각 설정에 대한 마킹 규칙을 설명합니다.
다음 표에서는 Unity linker가 어셈블리의 상위 레벨 유형을 식별하는 방식을 설명합니다.
|어셈블리 유형:||||마킹 규칙:|
| :— | :— | :— | :— | :— |
|
| 최소 | 낮음 | 중간 | 높음 |
|.NET 클래스 & 플랫폼 SDK 및 UnityEngine 어셈블리| 예방적 보존과 모든 link.xml에 정의된 모든 보존을 적용합니다. | 예방적 보존과 모든 link.xml에 정의된 모든 보존을 적용합니다. | 모든 link.xml 파일에 정의된 모든 보존을 적용합니다. | 모든 link.xml 파일에 정의된 모든 보존을 적용합니다. |
|씬에서 참조된 유형을 포함한 어셈블리| 어셈블리의 모든 유형과 멤버 마킹. | 어셈블리의 모든 유형과 멤버 마킹. | 다음을 마킹합니다.
• [RuntimeInitializeOnLoadMethod] 또는 [Preserve] 속성이 있는 모든 메서드
• 모든 link.xml에 정의된 보존
• 사전 컴파일된 어셈블리, 패키지, Unity 스크립트 또는 어셈블리 정의 어셈블리의 MonoBehaviour 및 스크립터블 오브젝트에서 파생된 모든 유형을 마킹합니다. | 다음을 마킹합니다.
• [RuntimeInitializeOnLoadMethod] 또는 [Preserve] 속성이 있는 모든 메서드
• 모든 link.xml에 정의된 보존
• 사전 컴파일된 어셈블리, 패키지, Unity 스크립트 또는 어셈블리 정의 어셈블리의 MonoBehaviour 및 스크립터블 오브젝트에서 파생된 모든 유형을 마킹합니다. |
|기타| 어셈블리의 모든 유형과 멤버 마킹. | 다음을 마킹합니다.
• 모든 공용 유형과 해당 유형의 공용 멤버
• [RuntimeInitializeOnLoadMethod] 또는 [Preserve] 속성이 있는 모든 메서드
• 모든 link.xml에 정의된 보존
• 사전 컴파일된 어셈블리, 패키지, Unity 스크립트 또는 어셈블리 정의 어셈블리의 MonoBehaviour 및 스크립터블 오브젝트에서 파생된 모든 유형 | 다음을 마킹합니다.
• 모든 공용 유형과 해당 유형의 공용 멤버
• [RuntimeInitializeOnLoadMethod] 또는 [Preserve] 속성이 있는 모든 메서드
• 모든 link.xml에 정의된 보존
• 사전 컴파일된 어셈블리, 패키지, Unity 스크립트 또는 어셈블리 정의 어셈블리의 MonoBehaviour 및 스크립터블 오브젝트에서 파생된 모든 유형 | 다음을 마킹합니다.
• [RuntimeInitializeOnLoadMethod] 또는 [Preserve] 속성이 있는 모든 메서드
• 모든 link.xml에 정의된 보존
• 사전 컴파일된 어셈블리, 패키지, Unity 스크립트 또는 어셈블리 정의 어셈블리의 MonoBehaviour 및 스크립터블 오브젝트에서 파생된 모든 유형 |
|테스트| [UnityTest] 속성이 있는 모든 메서드와 NUnit.Framework에서 정의한 속성으로 표시된 모든 메서드를 마킹합니다. |||||
Unity linker는 어셈블리의 루트를 식별한 후 해당 루트가 의존하는 코드를 식별해야 합니다. 다음 표에서는 Unity linker가 어셈블리의 루트 유형 종속성을 식별하는 방식을 설명합니다.
|규칙 타겟||||각 스트리핑 레벨의 행동|
| :— | :— | :— | :— | :— |
|
| 최소 | 낮음 | 중간 | 높음 |
|MonoBehaviour| Unity linker는 유형을 마킹할 때 MonoBehaviour 유형의 모든 멤버를 마킹합니다. ||||
|스크립터블 오브젝트| Unity linker는 유형을 마킹할 때 스크립터블 오브젝트 유형의 모든 멤버를 마킹합니다. ||||
|속성| Unity linker가 어셈블리, 유형이나 다른 코드 구조체를 마킹할 때 Unity linker는 또한 해당 구조체의 모든 속성을 마킹합니다. | Unity linker가 어셈블리, 유형이나 다른 코드 구조체를 마킹할 때 Unity linker는 또한 해당 구조체의 모든 속성을 마킹합니다. | Unity linker가 어셈블리, 유형이나 다른 코드 구조체를 마킹할 때 속성 유형도 마킹되는 경우 Unity linker는 해당 구조체의 속성만 마킹합니다. | Unity linker가 어셈블리, 유형이나 다른 코드 구조체를 마킹할 때 속성 유형도 마킹되는 경우 Unity linker는 해당 구조체의 속성만 마킹합니다. |
|디버깅 속성| 스크립트 디버깅을 활성화하면 Unity linker는 해당 멤버를 사용하는 코드 경로가 없어도 [DebuggerDisplay] 속성이 있는 모든 멤버를 마킹합니다. | 스크립트 디버깅을 활성화하면 Unity linker는 해당 멤버를 사용하는 코드 경로가 없어도 [DebuggerDisplay] 속성이 있는 모든 멤버를 마킹합니다. | Unity linker는 DebuggerDisplayAttribute 및 DebuggerTypeProxyAttribute 같은 디버깅 속성을 항상 제거합니다. | Unity linker는 DebuggerDisplayAttribute 및 DebuggerTypeProxyAttribute 같은 디버깅 속성을 항상 제거합니다. |
|.NET 파사드 클래스 라이브러리| 파사드 어셈블리는 런타임 시 필요하지 않기 때문에 제거합니다. |||||
Link.xml 파일은 자주 사용되지 않는 ‘기능’ XML 속성을 지원합니다. 예시에서 mscorlib.dll에 내장된 mscorlib.xml 파일은 이 속성을 사용하지만, 필요한 경우 모든 link.xml 파일에서 사용할 수 있습니다.
High 스트리핑 레벨을 사용할 때 Unity linker는 현재 빌드에 대한 설정을 기준으로 지원되지 않는 기능의 보존을 제외합니다.
예를 들어 다음의 link.xml 파일은 COM을 지원하는 플랫폼에 포함된 유형의 메서드 1가지 및 모든 플랫폼의 메서드 1가지를 지원합니다.
<linker>
<assembly fullname="Foo">
<type fullname="Type1">
<!--Preserve FeatureOne on platforms that support COM-->
<method signature="System.Void FeatureOne()" feature="com"/>
<!--Preserve FeatureTwo on all platforms-->
<method signature="System.Void FeatureTwo()"/>
</type>
</assembly>
</linker>
High 스트리핑 레벨을 사용하면 Unity linker는 코드 크기를 더 줄이기 위해 메서드 바디를 편집합니다. 이 섹션에서는 Unity linker가 메서드 바디에 적용한 주요 수정 사항을 요약합니다.
Unity linker는 .NET Class Library 어셈블리의 메서드 바디만 편집합니다. 메서드 바디 편집 후에는 어셈블리의 소스 코드가 더 이상 어셈블리의 컴파일된 코드와 일치하지 않으므로 디버깅이 더 어려워질 수 있습니다.
다음 리스트에서는 Unity linker가 메서드 바디를 편집하기 위해 수행할 수 있는 행동을 설명합니다.