IWYU

WYU(Include-What-You-Use) 종속성 모델을 사용하는 UE4의 업데이트된 코드 베이스에 대한 간략한 개요입니다.

Choose your operating system:

Windows

macOS

Linux

IWYU.png

IWYU (Include-What-You-Use)는 이름에서 알 수 있듯이 엔진의 소스 코드가 컴파일에 필요한 종속성만 포함한다는 의미입니다. IWYU의 목적은 Engine.h 또는 UnrealEd.h 와 같은 모놀리식 헤더 파일을 포함하지 않도록 함으로써 불필요한 종속성을 완화하는 것입니다. 다음 레퍼런스 가이드에서는 프로젝트가 IWYU 규칙을 준수하도록 하는 IWYU 활성화 방법에 대한 수준 높은 설명을 비롯하여 IWYU의 의미를 설명합니다. 또한 게임 프로젝트에 IWYU 모드를 사용하도록 선택한 경우 IWYU 모드 작업을 최대한 활용할 수 있는 몇 가지 일반적인 팁을 배울 수 있습니다.

IWYU 모드는 게임과 게임 플러그인에 대해 기본적으로 비활성화되어 있지만 엔진과 엔진 플러그인에 대해서는 기본적으로 활성화되어 있습니다.

IWYU의 의미

UE4(언리얼 엔진 4)의 예전 버전에서는 대부분의 엔진 기능이 Engine.hUnrealEd.h 와 같이 모듈 중심의 큰 헤더 파일에 포함되어 있었고 빠른 컴파일 시간은 PCH(Precompiled Header, 사전 컴파일된 헤더) 파일을 통해 빠르게 컴파일되는 이런 파일에 의존합니다. 엔진이 커지면서 이러한 구조는 병목 현상이 되었습니다.

IWYU를 사용하면 모든 파일에는 필요한 내용만 포함되며, 사용하기 위해 선택한 모든 PCH 파일은 기반 소스 파일 위에서 최적화 레이어로만 작동합니다. 파일은 소스 파일 자체의 변경 사항과 관계없이 빌드 시간을 최소화하고, 코드 컴파일의 성공 여부에는 영향을 미치지 않고 수정할 수 있습니다.

IWYU 코드를 작성할 때 사용하는 네 가지 구체적인 규칙이 있습니다.

  1. 모든 헤더 파일은 필수 종속성을 포함합니다.

  2. .cpp 파일은 일치하는 *.h 파일을 먼저 포함합니다.

  3. PCH 파일은 더 이상 명시적으로 포함되지 않습니다.

  4. 모놀리식 헤더 파일은 더 이상 포함되지 않습니다.

IWYU 규칙

다음 IWYU 규칙에 대한 설명은 IWYU의 의미를 이해하는 데 유용합니다.

  1. 모든 헤더 파일은 필수 종속성을 포함합니다.

    • UE4의 코어 프로그래밍 환경에서 (FString, FName, TArray 등을 포함한) 유비쿼터스 타입 세트가 포함된 CoreMinimal 헤더 파일이 있습니다.

    • \Engine\Source\Runtime\Core\Public\CoreMinimal.h 의 UE4 루트 디렉터리에 있는 CoreMinimal 헤더 파일은 대부분의 엔진 헤더 파일에 먼저 포함됩니다.

      CoreMinimalHeader.png

    • Core 모듈 내에서 대부분의 헤더 파일에는 CoreTypes.h 헤더 파일이 먼저 포함됩니다. 여기에는 프리미티브 C++ 타입, UE4 빌드 매크로, 컴파일 환경을 구성하기 위한 지시문에 대한 typedef만 포함됩니다.

    가장 중요한 점은 이제 모든 헤더 파일에 컴파일에 필요한 모든 것이 포함된다는 점입니다.

  2. .cpp 파일은 일치하는 *.h 파일을 먼저 포함합니다.

    CPPFileIncludingHeader.png

    • 모든 소스 파일에 필요한 모든 필수 종속성이 포함되어 있는지 검증하려면 PCH 파일을 비활성화한 상태에서 비Unity통합 모드로 게임 프로젝트를 컴파일합니다.

  3. PCH 파일은 더 이상 명시적으로 포함되지 않습니다.

    • PCH 파일은 계속 사용되지만 언리얼 빌드 툴(UBT)의 컴파일러 명령줄에서 강제로 포함됩니다.

  4. 모놀리식 헤더 파일은 더 이상 포함되지 않습니다.

    • 엔진 코드에 모놀리식 헤더 파일(예: Engine.h 또는 UnrealEd.h )이 포함되어 있으면 컴파일러에서 경고가 표시됩니다.

    모놀리식 헤더 파일은 게임 프로젝트와의 호환성을 위해 계속 UE4에 있으며, 게임 프로젝트에 모놀리식 헤더 파일이 포함되어 있으면 기본적으로 경고는 표시되지 않습니다.

IWYU 활성화 여부 검증하기

버전 4.15 출시와 함께 IWYU 규칙을 설정하기 전에 UE4 코드는 일반적으로 모든 CPP 파일 위에 PCH 파일을 포함합니다. 이러한 양상은 개발자가 IWYU 호환 코드에 포함하기를 원하는 것과 반대입니다. IWYU 규칙에 따라 PCH 파일은 코드가 원래 어떻게 작성되었는지와 관계없이 적용되는 컴파일 타임 최적화 레이어로 생각할 수 있습니다. 따라서 PCH 파일을 구성하고 포함하는 대신 (있는 경우) 어떤 PCH 파일을 사용할지는 UBT에 위임합니다.

IWYU가 활성화되어 있는지 검증하고 모듈이 IWYU 규칙을 준수하게 하려면 모듈의 *.build.cs 파일을 열고 `PCHUsage` 가 `PCHUsageMode.UseExplicitOrSharedPCHs` 로 설정되어 있는지 확인하세요.

ExamplePlugin_PCHUsage.png

PCHUsagePCHUsageMode.UseExplicitOrSharedPCHs 로 설정하면 모듈의 *.build.cs 파일에 `PrivatePCHHeaderFile` 세팅이 있는 경우에만 모듈에 대한 명시적인 PCH 파일을 생성합니다. 그렇지 않으면 모듈이 다른 모듈과 PCH를 공유하여 툴이 필요 이상으로 PCH 파일을 생성하지 않게 됩니다. 또한 `UseExplicitOrSharedPCHs` 모드를 활성화할 때는 소스 파일에 일치하는 헤더 파일을 포함해야 합니다. 또는 모듈에서 IWYU 규칙을 준수하지 않도록 하려면 `PCHUsage`를 `PCHUsageMode.UseSharedPCHs` 로 설정할 수 있습니다.

ExamplePlugin_UseSharedPCHs.png

엔진의 코드 베이스를 IWYU 모델로 변환한 후 UE4 컴파일 시간이 크게 향상되었습니다.

IWYU 모드에서 실행하기

게임을 IWYU 모드에서 실행하는 경우 먼저 .cpp 파일에 해당하는 .h 파일이 포함되어 있는지 확인해야 합니다. 이러한 방법은 컴파일러에서 (PCH 파일과 Unity 빌드가 비활성화된 경우) *.h 파일이 필요한 모든 종속성을 포함하는지 확인하도록 하기 때문에 유용합니다. 먼저 (해당 CPP 파일에 대해) 일치하는 헤더 파일이 포함되어 있지 않으면 언리얼 빌드 툴(UBT)에서 경고가 표시됩니다.

컴파일러에서 경고가 표시되지 않도록 비활성화하려면 모듈의 *.build.cs 파일에서 `bEnforceIWYU` 를 `false` 로 설정할 수 있습니다.

ModuleBuildCS_bEnforceIWYUfalse.png

전체 타깃에 대한 경고를 비활성화하려면 *.target.cs 파일에서 `bEnforceIWYU` 를 false로 설정할 수 있습니다.

일반적인 팁

게임이 IWYU를 준수하게 하려고 할 때 염두에 두어야 하는 팁이 몇 가지 있습니다.

  1. 각 헤더 파일 맨 위에 CoreMinimal.h 를 포함합니다.

  2. 모든 소스 파일에 필요한 모든 종속성이 포함되어 있는지 검증하려면 PCH 파일을 비활성화한 상태에서 비Unity 모드로 게임 프로젝트를 컴파일합니다.

  3. Runtime\Engine\Classes\Engine\Engine.h 에 정의된 UEngine 또는 GEngine 에 액세스해야 하는 경우 #include Engine/Engine.h 를 사용할 수 있습니다(Runtime\Engine\Public\Engine.h 에 위치한 모놀리식 헤더 파일과 다름).

  4. 컴파일러에서 인식하지 못하는 클래스를 사용하고 어떤 것을 포함해야 할지 모를 경우 헤더 파일이 누락될 수 있습니다. 올바르게 컴파일된 비IWYU 코드에서 변환하는 경우 더욱 그렇습니다. API 문서에서 클래스를 조회하여 페이지 하단에서 필수 모듈 및 헤더 파일을 찾을 수 있습니다.

추가 리소스

기존 C++ 프로젝트를 IWYU 스타일로 변환하는 데 도움을 드리기 위해 IncludeTool 을 출시했습니다. IncludeTool은 [UE4Root]\Engine\Source\Programs\IncludeTool 에 있습니다.

언리얼 엔진의 이전 버전을 위해 작성된 페이지입니다. 현재 언리얼 엔진 5 버전을 위해 업데이트되지 않았습니다.