IncludeTool

기존 C++ 프로젝트를 IWYU(Include-What-You-Use) 스타일로 변환하는 데 사용하는 IncludeTool의 레퍼런스 가이드입니다.

Choose your operating system:

Windows

macOS

Linux

경고: IncludeTool은 언리얼 엔진 4(UE4)를 비롯하여 여러 내부 에픽 프로젝트를 변환하는 데 사용되었습니다. 이 툴은 무료로 제공되지만 제공할 수 있는 지원의 수준은 제한되어 있습니다. 이 툴은 무료로 제공되지만 제공할 수 있는 지원의 수준은 제한되어 있습니다.

IncludeTool 유틸리티는 기존 C++ 프로젝트를

[IWYU(Include-What-You-Use)](ProductionPipelines/BuildTools/UnrealBuildTool/IWYU)
스타일로 변환하는 데 사용할 수 있습니다. 각 헤더 파일의 독립적인 트랜슬레이션 유닛을 형성하려고 함으로써 이러한 작업을 수행합니다. 이 유틸리티를 통해 많은 시간을 절약할 수 있지만 휴리스틱 기법을 기반으로 하며, 완벽한 출력을 생산하기보다는 트랜지션을 완료하기 위한 수동 편집을 시작할 좋은 위치를 만들어 줍니다. 하지만 무차별 대입(대규모 프로젝트의 경우 완료하는 데 약 며칠이 걸릴 정도로 느립니다)으로 작동하고, 쉽게 반복작업할 수 없으며, 프로젝트별로 수정해야 할 수 있고, 디버그하기 어려울 수도 있습니다.

툴 작업

IncludeTool은 몇 가지 단계로 작동하는데, 아래에서 설명합니다.

  • 타깃에서

    [언리얼 빌드 툴](ProductionPipelines/BuildTools/UnrealBuildTool)
    이 호출되어 빌드 단계의 목록을 생성합니다. 다른 타깃 타입보다 더 많은 코드 경로를 포함하므로 프로젝트의 에디터 타깃을 사용하는 것이 좋습니다. Clang 툴 체인을 사용하기 위해 Windows의 크로스 컴파일 툴 체인을 사용하여
    [Linux용으로 컴파일](sharing-and-releasing-projects/Linux/GettingStarted)
    하는 것이 좋습니다. Visual C++는 2단계 이름 조회를 수행하지 않아 템플릿이 인스턴스화될 때까지 템플릿 클래스에서 종속 클래스에 대한 종속성을 찾지 못합니다. 결과적으로 매우 읽기 어려운 출력을 생성하기 때문에 Clang을 사용하는 것이 중요합니다. 

  • 소스 파일은 내부 프리프로세서를 사용하여 부분적으로 사전 처리됩니다. 토큰화된 소스 파일 자체는 변환하지 않지만 현재 타깃에 대해 어떤 코드 블록이 활성화 및 비활성화인지 파악하고 각 파일을 여러 개의 프래그먼트로 나눕니다. 각 프래그먼트는 소스 파일에서 #include 지시문 사이의 여러 줄을 정의합니다. 즉, 모든 소스 파일의 단일 파일 버전은 #include 지시문을 재귀적으로 따르고 발견한 프래그먼트의 목록을 연결하여 언제든 어셈블할 수 있습니다.

  • 이 단계는 IncludeTool이 최적화할 프래그먼트 목록이기 때문에 중요합니다. IncludeTool이 이 단계 동안 유효성을 검사하고 경고를 표시하는 몇 가지 제한이 있습니다. 일부 경고는 너무 세세하고 기교를 부리는 문체를 사용하는 것처럼 보이지만 출력이 유효한지 확인하는 데 필요합니다. 특히 주목할 만한 사항은 다음과 같습니다.

    • 헤더 파일 사이에 순환 인클루드가 포함되어 있으면 안 됩니다.

    • 포함된 소스 파일은 모든 변환 유닛에 의해 동일한 방식으로 사전 처리되어야 합니다(예: 모든 매크로는 포함된 컨텍스트에서 동일하게 정의되어야 함).

  • 각 프래그먼트는 작업 폴더에 작성됩니다. 각 소스 파일은 줄 번호를 유지하기 위해 오리지널 레이아웃으로 출력되는데, 다른 프래그먼트에 속하는 줄은 주석으로 처리됩니다.

  • 소스 파일은 토큰화되어 이후 선언할 수 있는 심볼처럼 보이는 패턴을 검색합니다. (예: "클래스 Foo { ...")

  • 각 소스 파일은 무차별 대입 컴파일을 통해 어떤 프래그먼트에 의존하여 성공적으로 컴파일할지 결정합니다. 이 부분은 변환에서 가장 노동 집약적인 부분이지만 이 분석 결과는 작업 디렉터리에 저장되며 소스 파일이 변경되지 않으면 다시 사용할 수 있습니다. 이 툴은 또한 다중 PC를 사용하기 위해 '공유' 모드를 지원하여 종속성 데이터를 계산합니다(아래 참조).

  • 검색의 구조는 다음과 같습니다.

    • 입력 트랜슬레이션 유닛이 확장되어 프래그먼트 시퀀스대로(1...n) 표시됩니다.

    • 필수 프래그먼트(r) 세트는 (입력 파일에 포함되지 않고) 입력 파일에 있는 프래그먼트에만 초기화됩니다.

    • 바이너리 검색이 수행되어 소스 파일을 성공적으로 컴파일하는 데 필요한 가장 긴 프래그먼트 시퀀스를 찾습니다(1...m, r 포함).

    • 시퀀스의 마지막 프래그먼트(m)가 필수 세트(r)에 추가됩니다. 'm'이 이미 최적화되었으면 종속성도 r에 추가됩니다.

    • 프래그먼트 시퀀스(1...m - 1)에 대해 바이너리 검색이 반복됩니다.

  • 각 출력 파일은 최소 인클루드 세트로 작성되어 독립적으로 컴파일됩니다. 휴리스틱 기법은 이름을 통해 명시적으로 참조되는 심볼을 포함하는 모든 종속성에 대한 헤더를 직접 포함하려 하며, 재귀적으로 포함되지 않을 경우 다른 종속성만 포함합니다.

샘플 사용

프래그먼트 분석 수행 및 진단 정보 출력:

-Mode=Scan -Target=FooEditor -Platform=Linux -Configuration=Development -WorkingDir=D:\Working

코드베이스 최적화:

-Mode=Optimize -Target=FooEditor -Platform=Linux -Configuration=Development -WorkingDir=D:\Working -OutputDir=D:\Output -SourceFiles=-/Engine/... -OptimizeFiles=-/Engine/... -OutputFiles=-/Engine/...

몇몇 필터 실행인자를 전달하여 소스 파일 반복작업(-SourceFiles , -OptimizeFiles , -OutputFiles )을 제한할 수 있습니다. 각 항목에는 P4 스타일 와일드카드의 세미콜론 목록을 사용하여 파일을 포함(/Engine/... ) 또는 제외(-/Engine/Foo.cpp )하거나 줄 당 작성(D:\Filter.txt )을 통해 규칙으로 응답 파일을 지정할 수 있습니다. 일반적으로 엔진 코드를 다시 최적화할 이유는 없기 때문에 분석에서 이러한 파일을 모두 제외하는 것이 좋습니다.

프로그램을 실행하는 데 시간이 너무 오래 걸릴 수 있기 때문에 '공유' 모드로 실행하는 기능이 있습니다. 동일한 소스 트리로 모두 동기화되는 PC 여러 대가 있는 경우 -Shard=N-NumShards=M 을 사용하여 입력 세트의 일부만 고려하도록 머신을 환경설정할 수 있습니다. 작업 디렉터리는 각 머신에서 동일한 위치에 있어야 하며 그에 따른 작업 디렉터리는 함께 복사하여 단일 머신에서 출력 파일을 생성하는 최종 실행에 사용할 수 있습니다.

참고:  Program.cs 에서 다른 모드(ToolMode 열거형 검색)에 대한 주석과 명령줄 옵션(CommandLineOptions 클래스)을 확인하세요.

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