언어:
페이지 정보
엔진 버전:
언리얼 엔진

IWYU 레퍼런스 가이드

언리얼 엔진
사전 필수 토픽

이 페이지는 다음 토픽에 대한 지식을 이미 갖추고 있는 분들을 대상으로 합니다. 계속하기 전 먼저 읽어보시기 바랍니다.

IWYU.png

Include-What-You-Use (IWYU), 이름이 암시하듯, 엔진의 소스 코드가 컴파일해야 하는 종속성만 포함시킨다는 뜻입니다. IWYU 는 Engine.hUnrealEd.h 처럼 모놀리식 헤더 파일을 포함시키지 않고, 종속성 과잉 현상을 경감시킵니다. 다음 레퍼런스 가이드는 IWYU 가 무슨 뜻인지 일반적인 수준의 설명에서부터 IWYU 를 켜서 프로젝트가 IWYU 규칙을 준수하도록 하는 법을 알려드립니다. 추가적으로 게임 프로젝트에 IWYU 모드를 사용하기로 한 경우, IWYU 모드를 최대한 활용하는 법에 도움이 되는 일반적인 팁을 몇 가지 알려드리겠습니다.

IWYU 모드는 게임 및 게임 플러그인에 기본으로 꺼져 있으나, 엔진 및 엔진 플러그인에는 기본으로 켜집니다.

IWYU 의 의미

언리얼 엔진 4 (UE4) 기존 버전에서, 엔진 기능 대부분은 Engine.hUnrealEd.h 같은 커다란 모듈 집중형 헤더 파일을 통해 포함되고 있었으며, 이 파일들이 프리컴파일드 헤더 (PCH) 파일을 통해 빠르게 컴파일되느냐에 따라 빠른 컴파일 시간이 좌우됩니다. 엔진이 커지면서, 이 부분이 병목 현상이 되었습니다.

IWYU 로 모든 파일은 필요한 것과 사용하도록 선택한 PCH 파일만 포함시키며, 순수히 내재된 소스 파일 위의 최적화 층 역할을 합니다. 변경을 통해 빌드 시간을 최소화시키고, 소스 파일 자체의 독립적 변경이 가능하며, 코드 컴파일 성공 여부에는 영향을 끼치지 않습니다.

IWYU 코드 작성 시 채택하고 있는 규칙은 구체적으로 네 가지입니다:

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

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

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

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

IWYU 규칙

다음 IWYU 규칙 설명으로 IWYU 가 무슨 뜻인지 개념을 잡기가 좋을 것입니다.

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

    • UE4 코어 프로그래밍 환경 어디에나 존재하는 (FString, FName, TArray 등) 유형 세트가 들어있는 CoreMinimal 헤더 파일이 있습니다.

    • CoreMinimal 헤더 파일은 (UE4 루트 디렉터리 아래 \Engine\Source\Runtime\Core\Public\CoreMinimal.h 에 위치해 있으며,) 엔진의 헤더 파일 대부분에 먼저 포함됩니다.

    CoreMinimalHeader.png

    • Core 모듈 안에 대부분의 헤더 파일은 CoreTypes.h 헤더 파일을 먼저 포함합니다. 초기 C++ 유형의 typedefs, UE4 빌드 매크로, 컴파일 환경 구성을 위한 디렉티브만 포함합니다.

    주안점은 모든 헤더 파일이 이제 컴파일해야 하는 모든 것을 포함한다는 것입니다.

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

    CPPFileIncludingHeader.png

    • 모든 소스 파일이 모든 필수 종속성을 포함했는지 검증하기 위해서는, PCH 파일을 끄고 게임 프로젝트를 non-unity 모드로 컴파일하면 됩니다.

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

    • PCH 파일은 여전히 사용되나, UnrealBuildTool (UBT) 가 컴파일러 명령줄에서 강제 포함시킵니다.

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

    • 엔진 코드에 (Engine.hUnrealEd.h 같은) 모놀리식 헤더 파일이 포함되면 컴파일러가 경고를 냅니다.

    UE4 에 모놀리식 헤더 파일이 아직 존재하는 이유는 게임 프로젝트와의 호환성 때문이며, (기본적으로) 게임 프로젝트가 포함하는 경우 경고가 나지 않습니다.

IWYU 켜기

4.15 버전 릴리즈로 IWYU 규칙이 수립되기 전, UE4 코드는 보통 모든 CPP 파일 상단에 PCH 파일을 포함하는데, 이는 개발자가 IWYU 준수 코드를 포함시키려는 경우에 반하는 것입니다. 새로 확립된 IWYU 규칙에서, PCH 파일은 코드를 원래 어떻게 작성했는가와는 별개로 적용되는 컴파일 시간 최적화 층으로 생각해 볼 수 있습니다. 그래서 PCH 파일을 만들어 포함하기 보다는, 그냥 UBT 가 사용할 PCH 파일을 (있으면) 결정하도록 놔둡니다.

IWYU 모드를 켜려면, 모듈이 IWYU 규칙으로 컴파일되는지 확인하고, 모듈의 *.build.cs 파일을 열어 PCHUsagePCHUsageMode.UseExplicitOrSharedPCHs 로 설정하면 됩니다.

ExamplePlugin_PCHUsage.png

PCHUsagePCHUsageMode.UseExplicitOrSharedPCHs 로 설정하면 모듈이 *.build.cs 파일에 PrivatePCHHeaderFile 세팅이 있는 경우에만 그 모듈에 대한 명시적 PCH 파일을 생성합니다. 그렇지 않으면 그 모듈은 다른 모듈과 PCH 를 공유하여, 툴이 필요한 것보다 많은 PCH 파일을 생성하지 못하도록 합니다. 또한 UseExplicitOrSharedPCHs 모드를 켤 때, 소스 파일이 반드시 일치하는 헤더 파일을 포함해야 한다는 점에 유념하세요. 다른 방법으로, 모듈이 IWYU 규칙을 준수하지 않도록 하려면, PCHUsagePCHUsageMode.UseSharedPCHs 로 설정하면 됩니다.

ExamplePlugin_UseSharedPCHs.png

엔진의 코드 베이스를 IWYU 모델로 변환한 이후, UE4 컴파일 시간이 크게 빨라진 것을 목격했습니다.

IWYU 모드로 실행

게임을 IWYU 모드로 실행하는 경우, *.cpp 파일이 그에 상응하는 *.h 파일을 먼저 포함하도록 해줘야 합니다. 컴파일러에서 *.h 파일이 (PCH 파일 및 unity 빌드가 꺼졌을 때) 필수 종속성 전부를 포함할 수 있도록 해주기 때문입니다. 언리얼 빌드 툴(UBT)은 (상응하는 CPP 파일에 대해) 일치하는 헤더 파일을 먼저 포함하지 않는 경우 경고를 냅니다.

컴파일러가 이미터 경고를 내지 못하도록 하려면, 모듈의 *.build.cs 파일에서 bEnforceIWYUfalse 로 설정합니다.

ModuleBuildCS_bEnforceIWYUfalse.png

전체 타깃에 경고를 끄려면, *.target.cs 파일에서 bEnforceIWYUfalse 로 설정하면 됩니다.

일반 팁

게임에서 IWYU 를 사용하고자 할 때 염두에 두어야 할 팁이 몇 가지 있습니다:

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

  2. 모든 소스 파일에 모든 필수 종속성이 포함되는지 검증하려면, PCH 파일을 끄고 non-unity 빌드로 게임 프로젝트를 컴파일합니다.

  3. Runtime\Engine\Classes\Engine\Engine.h 에 정의된 UEngine 또는 GEngine 에 접근하려면, (Runtime\Engine\Public\Engine.h 에 위치한 모놀리식 헤더 파일과 구분해서) #include Engine/Engine.h 하면 됩니다.

  4. 컴파일러가 인식하지 못하는 클래스를 사용하는데, 무엇을 포함시킬지 모르는 경우 헤더 파일이 없을 수 있습니다. 제대로 컴파일되는 비 IWYU 코드에서 변환하는 경우 특히 그렇습니다. API Documentation 에서 클래스를 찾아 페이지 하단에서 필요한 모듈과 헤더 파일을 확인할 수 있습니다.