티스토리 뷰

https://developer.apple.com/documentation/xcode/improving-the-speed-of-incremental-builds

Improving the Speed of Incremental Builds

Xcode 빌드 시스템에 프로젝트의 타겟 관련 의존성을 알고 각 빌드 주기 동안 컴파일러 작업량을 줄입니다.

Overview

Xcode 빌드 시스템은 타겟의 코드 컴파일 및 링크를 관리합니다.

일반적인 유형의 대상에는 앱, 앱 extension, 프레임워크, 라이브러리 및 테스트 제품군이 포함됩니다.

단순 프로젝트에는 빌드하려는 앱과 같이 하나의 대상만 포함될 수 있습니다.

보다 복잡한 프로젝트에는 개인 프레임워크 및 해당 프레임워크에 의존하는 앱과 같이 상호 의존성이 있는 여러 대상이 포함될 수 있습니다.

 

 

프로젝트의 타겟 간 의존성 및 구성 세부 정보가 정확한지 항상 확인하세요.

타겟을 빌드할 때 Xcode는 병렬로 최대한 많은 작업을 수행합니다.

의존성이 적으면 병렬화가 더 커지지만 빌드 및 런타임 오류를 방지하려면 정확한 의존성 맵이 필요합니다.

마찬가지로, 자세한 구성 데이터를 제공하면 Xcode가 빌드 시간 작업을 정확하고 효율적으로 스케줄링하는 데 도움이 됩니다.

 

Note

Following coding best practices can also improve Xcode’s efficiency during compilation. For more information, see Improving Build Efficiency with Good Coding Practices.

 

 

Measure the Time It Takes for Each Build Task

빌드 최적화를 수행하기 전에 항상 타이밍 정보를 수집하여 최적화가 가장 효과적인 위치를 확인하십시오.

Xcode에서 프로젝트를 열고 Product > Perform Action > Build With Timing Summary를 선택하여 세부 타이밍 정보로 타겟을 구축합니다.

특정 빌드에 대한 타이밍 정보를 보려면 Report navigator에서 해당 빌드를 선택합니다.

Note

To generate timing information using the xcodebuild command-line tool, pass the -showBuildTimingSummary option to the tool.

프로젝트를 처음 빌드할 때 Xcode는 모든 것을 빌드하지만 이후 빌드는 증분 빌드입니다.

각 증분 빌드에 대해 준비 섹션과 각 대상에 대해 Xcode가 수행하는 특정 작업에 특히 주의를 기울입니다.

  • Xcode가 대상을 병렬로 빌드하지 않은 경우 대상의 Scheme Editor를 열고 병렬화 빌드 옵션이 활성화되어 있는지 확인하십시오.
  • 사용자 지정 스크립트와 같은 관련 없는 작업을 찾고 각 증분 빌드 중에 Xcode가 이러한 스크립트를 실행해야 하는지 여부를 평가합니다.
  • 특정 파일의 컴파일 시간이 다른 파일보다 상당히 오래 걸리는 경우 파일을 검사하여 헤더 가져오기 문제로 인해 지연이 발생하는지 확인하세요.

 

Declare Inputs and Outputs for Custom Scripts and Build Rules

Xcode 프로젝트에서 사용자 지정 빌드 스크립트를 사용하는 경우 Xcode에서 해당 스크립트를 필요한 경우에만 실행해야 합니다.

스크립트를 사용하여 사용자 지정 도구를 실행하거나, 빌드 환경 변수를 프로그래밍 방식으로 설정하거나, 다른 대상별 작업을 수행할 수 있습니다.

예를 들어 이러한 파일을 사용하여 독점 데이터 원본에서 자산 또는 기타 리소스 파일을 생성할 수 있습니다.

기본적으로 Xcode는 증분 빌드를 포함하여 모든 빌드 주기 동안 사용자 지정 스크립트를 실행합니다.

또한 다른 작업과 관련하여 해당 스크립트를 연속적으로 실행합니다.

 

 

대상을 빌드할 때마다 스크립트를 실행하는 데 Xcode가 필요하지 않은 경우, 스크립트에 대한 입력 파일과 출력 파일을 하나 이상 제공하세요.

Xcode는 스크립트의 입력 및 출력 파일을 사용하여 실행할 시기를 결정합니다.

특히 Xcode는 다음 조건 중 하나에 해당하는 경우 스크립트를 실행합니다.

  • 스크립트에 입력 파일이 없습니다.
  • 스크립트에 출력 파일이 없습니다.
  • 스크립트의 입력 파일이 변경되었습니다.
  • 스크립트의 출력 파일이 사라졌습니다.

 

Run Script build-phase 편집기에서 스크립트 자체와 함께 입력 및 출력 파일을 지정합니다.

입력 및 출력 파일을 개별적으로 지정하거나 Xcode 파일 목록(각 파일의 이름을 별도의 줄에 나열하는 .xcfilelist 확장자를 가진 파일)에 지정할 수 있습니다.

스크립트가 실제로 이러한 파일을 필요로 하지 않더라도 항상 Xcode가 스크립트를 실행하지 못하도록 하려면 입력 및 출력 파일을 지정해야 합니다.

입력이 필요 없는 스크립트의 경우 입력 파일로 변경되지 않는 파일을 제공합니다.

출력이 없는 스크립트의 경우 스크립트에서 정적 출력 파일을 생성하여 Xcode에서 확인할 수 있도록 합니다.

 

 

Create Module Maps for Custom Frameworks and Libraries

모듈 맵은 헤더 파일을 가져오는 데 걸리는 시간을 단축하여 소스 컴파일 시간을 향상시킵니다.

모듈 맵은 컴파일러에게 프레임워크에 포함된 헤더 목록을 제공합니다.

프레임워크가 모듈 맵을 포함할 때 컴파일러는 각 소스 파일에 대해 헤더 파일을 별도로 사전 처리하지 않습니다.

대신 프레임워크의 symbol 정보의 캐시를 구축하고 후속 컴파일 중에 캐시를 재사용하여 상당한 시간을 절약합니다.

 

 

시스템 프레임워크에는 이미 모듈 맵이 포함되어 있지만 프로젝트의 사용자 지정 프레임워크에 대한 모듈 맵을 제공해야 합니다.

모듈 맵을 추가하려면 프레임워크 또는 라이브러리에 대해 DEFINES_MODULE 빌드 설정을 사용합니다.

Xcode는 새 프레임워크에 대해 이 빌드 설정을 자동으로 사용하도록 설정하지만 이전 프로젝트에 대해 설정해야 할 수도 있습니다.

이 옵션을 선택하면 컴파일러는 대상의 공개 헤더 파일 내용이 포함된 모듈 맵을 생성합니다.

 

💡 모듈 맵의 이점을 얻으려면 항상 import문에 프레임워크 이름을 포함하세요. 프레임워크 이름을 포함하지 않으면 컴파일러는 모듈 맵이 있는지 여부를 확인할 수 없습니다. For more information on how to import header files from a module, see Include Framework Names in Import Statements.

 

 

모듈 맵을 작성하기 전에 프레임워크가 다음 요구 사항을 충족하는지 확인하세요.

  • 프레임워크의 헤더 파일은 외부 상황 정보에 의존해서는 안 됩니다. Xcode는 프로젝트의 나머지 원본 파일과 별도로 모듈 맵을 컴파일합니다. 헤더에 있는 symbols의 의미나 값을 변경하기 위해 소스별 정보에 의존하지 마세요.
  • 모듈은 자신을 포함해야합니다. Xcode는 모듈 맵을 별도로 컴파일하기 때문에 프레임워크의 헤더 파일은 올바르게 컴파일하는 데 필요한 모든 것을 포함해야 합니다.

 

모듈 맵을 최대한 재사용하려면 동일한 빌드 옵션을 사용하여 앱의 소스 파일을 컴파일하십시오.

Xcode는 해당 프레임워크를 가져오는 원본 파일과 동일한 옵션을 사용하여 프레임워크의 모듈 맵을 작성합니다.

앱의 소스 파일이 다른 옵션을 사용하는 경우 Xcode는 각 새 옵션 집합에 대해 모듈 맵을 다시 컴파일해야 합니다.

동일한 옵션을 사용하면 Xcode가 각 후속 소스 파일의 캐시를 재사용할 수 있습니다.

 

 

Make Sure Your Target’s Dependencies Are Accurate

타겟이 정확한 의존성을 가지고 있는지 확인하면 정확하고 적시에 빌드하는 것을 보장할 수 있습니다.

오래된 의존성은 Xcode가 대상을 병렬로 빌드했을 때 Xcode가 대상을 직렬로 빌드하도록 강제할 수 있습니다.

의존성이 누락되면 정확성 문제가 발생하거나 빌드 오류가 발생할 수 있습니다.

예를 들어, 앱 확장과 같이 별도의 코드 모듈에 명시적으로 종속되지 않는 경우 Xcode는 제대로 작동하지 않는 이전 버전의 모듈을 사용하여 앱을 빌드할 수 있습니다.

 

 

Xcode 프로젝트의 두 대상 사이에 의존성이 있다는 것을 알면 이들 대상 사이에 의존성을 명시적으로 생성합니다.

Xcode는 프로젝트를 구성하는 방법에 따라 일부 의존성을 자동으로 생성합니다.

예를 들어 기존 앱에 새 프레임워크를 내장하면 Xcode가 자동으로 해당 프레임워크를 앱의 의존성 목록에 추가합니다.

또한 다음과 같이 Dependencies build phase 편집기를 사용하여 종속성을 직접 지정할 수도 있습니다.

+, - 버튼을 사용하여 대상에 대한 종속성을 추가하거나 제거합니다.

 

타겟이 다른 Xcode 프로젝트의 코드에 의존하는 경우 현재 프로젝트의 네비게이션 창으로 끌어 해당 프로젝트에 대한 참조를 만듭니다.

네비게이션 창에 다른 프로젝트가 있으면 Xcode가 다른 프로젝트의 항목에 대한 의존성을 추적하는 데 필요한 정보를 얻을 수 있습니다.

이 참조가 없으면 Xcode는 원격 프로젝트가 변경되었을 때 대상을 빌드할 수 없습니다.

 

Refactor Your Targets to Improve Parallelism

타겟 간 의존성은 Xcode가 해당 대상을 특정 순서로 구축해야 한다.

타겟에 많은 의존성이 있거나 큰 단일 모듈에 의존하는 경우, Xcode는 더 많은 작업을 직렬화해야 합니다.

빌드 성능을 향상시키려면 대상의 종속성 목록을 단순화하고 단일 대상을 분리하여 Xcode가 병렬로 더 많은 작업을 수행할 수 있도록 하세요.

 

 

단일 유틸리티 프레임워크에 의존하는 XML 엔진을 보여주는 다음 그림을 살펴봅시다.

XML 엔진은 프레임워크의 작은 부분에만 의존하지만 Xcode는 프레임워크의 어떤 부분이 변경되면 엔진을 다시 빌드해야 합니다.

프레임워크를 더 작은 모듈로 나누고 더 세분화된 의존성을 만들면 불필요한 재 빌드를 제거할 수 있습니다.

리팩터링된 버전에서는 유틸리티 프레임워크의 변경 사항이 더 이상 XML 엔진의 자동 재빌드를 트리거하지 않습니다.

 

하나의 대상이 여러 하위 대상에 의존하면 Xcode는 모든 하위 대상을 완료할 때까지 타겟 빌드를 시작할 수 없습니다.

앱, 앱 extension 및 개인 프레임워크에서 자동화된 테스트를 실행하는 단일 테스트 타겟을 고려하세요.

테스트를 타겟별로 분할하면 Xcode는 해당 타겟이 준비되는 즉시 각 제품군을 독립적으로 실행할 수 있으므로 병렬화가 증가합니다.

 

프로젝트의 타겟을 수정하면 이점이 있는지 여부를 결정해야 합니다.

타겟 수를 늘리면 병렬화를 개선할 수 있지만 프로젝트의 복잡성도 증가합니다.

항상 타겟 또는 의존성 변경 사항을 확인하여 코드가 올바르게 빌드되는지 확인하세요.

또한 항상 결과 빌드 속도를 측정하여 변경 사항이 분명한 개선으로 이어졌는지 확인하세요.

댓글
공지사항