Xcode 11이 너무 많은 재 컴파일


12

Xcode 11은 로컬 개인 변수를 변경하거나 로컬 범위, 때로는 로컬 개인 함수 범위에서 상수 값을 변경하더라도 프로젝트 전체를 다시 컴파일합니다 (거의?). 언젠가는 예상대로 빠른 빌드로 2 ~ 3 개의 변경 사항을 얻을 수 있지만 곧 모든 것을 다시 컴파일하기로 결정합니다 (너무 오래 걸립니다).

어떤 아이디어가 진행되고 있습니까? Xcode가 변경된 것을 결정할 수 없습니까? 왜 그렇게 많은 다른 것들 (다른 모듈조차도)을 다시 컴파일합니까?

모든 조언에 감사드립니다!


2
나는 조언 할 것이다 : 전체 모듈 최적화가 아닌 증분 빌드로 디버그 빌드를 수행하고 있는지 확인하십시오. DerivedData를 종료하고 정리하십시오. 그리고 Xcode 11.4로 업데이트하면 때로는 너무 빨리 컴파일되어 발생조차하지 않습니다.
매트

1
이 글타래는 귀하의 질문에 답변 할 것입니다 : stackoverflow.com/questions/25537614/…
Endanke

프로젝트에 매우 의존적이며 진행 상황에 대한 빌드 로그를 분석해야합니다. Xcode 11.2 이상에서는 그러한 동작을 관찰하지 못하지만 매우 큰 프로젝트가 있습니다. 어떻게 든 프로젝트 소스에 액세스 할 수 있습니까? 그렇지 않으면 모든 조언이 의미가 없습니다.
Asperi

레거시 빌드 시스템 특성을 점검하십시오. 서브 모듈을 수정하지 않는 경우 선택 취소해야합니다.
BrunoLoops

답변:


8

우리는 같은 문제를 겪었고 그것을 고쳤습니다. 두번.

증분 빌드 (동일 빌드 머신) :

전 : ~ 10m 후 : ~ 35s

어떻게?

먼저 경험을 시작합시다. 우리는 방대한 Swift / Obj-C 프로젝트를 가지고 있었고 주요 관심사였습니다. 빌드 시간이 느리고 새로운 기능을 구현하기 위해 새로운 프로젝트를 작성해야했습니다 (문자 그대로). 결코 작동하지 않는 구문 강조를위한 보너스 포인트.

이론

이 문제를 진정으로 해결하려면 빌드 시스템 작동 방식 을 진정으로 이해해야 합니다. 예를 들어이 코드 스 니펫을 사용해 보겠습니다.

import FacebookSDK
import RxSwift
import PinLayout

파일에서이 모든 가져 오기를 사용한다고 상상해보십시오. 또한이 파일은 다른 라이브러리에 의존하는 다른 파일에 의존하며 다른 라이브러리에 의존합니다.

따라서 파일을 컴파일하려면 Xcode는 언급 한 모든 라이브러리라이브러리가 의존하는 모든 파일 을 컴파일해야 하므로 "코어"파일 중 하나를 변경하면 Xcode는 문자 그대로 전체 프로젝트를 다시 작성해야합니다.

의존성 트리

Xcode 빌드는 멀티 스레드 이지만 많은 단일 스레드 트리 로 구성됩니다 .

따라서 모든 증분 빌드의 첫 번째 단계에서 Xcode는 다시 컴파일 할 파일을 결정하고 AST 트리를 빌드합니다 . 다른 파일에서 " 신뢰할 수있는 " 것으로 작동하는 파일을 변경하면 " 종속 "으로 작동하는 다른 모든 파일을 다시 컴파일해야합니다.

커플 링

따라서 첫 번째 조언은 커플 링낮추는 것 입니다. 프로젝트 부분은 서로 독립적이어야합니다.

Obj-C / 스위프트 브리지

Obj-C / Swift 브리지를 사용하는 경우 Xcode는 평소보다 더 많은 단계를 거쳐야합니다.

완벽한 세상:

  1. Obj-C 코드 작성
  2. 스위프트 코드 빌드

스위프트 / Obj-C 브리지

Obj-C / 스위프트 브리지 :

  1. [반복 가능한 단계] Obj-C 코드를 컴파일하는 데 필요한 스위프트 코드 작성
  2. [반복 가능한 단계] Swift 코드를 컴파일하는 데 필요한 Obj-C 코드 빌드
  3. 의존 할 수없는 Swift & Obj-C 코드 만 남을 때까지 1 & 2를 반복하십시오.
  4. Obj-C 코드 작성
  5. 스위프트 코드 빌드

Obj-C / 스위프트 브리지

따라서 1 단계 또는 2 단계에서 무언가를 변경하면 기본적으로 문제가있는 것입니다. 가장 좋은 솔루션은 Obj-C / Swift Bridge를 최소화하고 프로젝트에서 제거하는 것입니다.

Obj-C / Swift Bridge가 없다면 훌륭합니다. 다음 단계로 넘어가십시오.

스위프트 패키지 관리자

SwiftPM으로 이동할 시간입니다 (또는 적어도 Cocoapod를 더 잘 구성하십시오).

기본 Cocoapods 구성을 가진 대부분의 프레임 워크는 필요하지 않은 많은 것들과 함께 드래그됩니다.

이를 테스트하려면 PinLayout과 같은 하나의 종속성으로 빈 프로젝트를 만들고 Cocoapods (기본 구성) 및 SwiftPM으로이 코드를 작성하십시오.

import PinLayout

final class TestViewController: UIViewController {

}

스포일러 : Cocoapods는 PinLayout의 모든 수입 (UIKit 포함)을 가져오고 SwiftPM은 프레임 워크를 원자 적으로 가져 오기 때문에 SwiftPM은 가져 오지 않기 때문에이 코드를 컴파일합니다.

더러운 해킹

Xcode 빌드가 다중 스레드임을 기억하십니까?

프로젝트를 여러 개의 독립적 인 조각으로 분할하여 모든 프로젝트를 독립적 인 프레임 워크로 가져올 수 있다면이를 남용 할 수 있습니다. 커플 링을 낮추고 실제로 우리가 사용한 첫 번째 솔루션 이었지만, 실제로는 그다지 효과적이지 않았습니다. 첫 번째 방법과 비교하여 증분 빌드 시간을 ~ 4-5m로 줄일 수 있었기 때문입니다.


행운을 빈다 프로젝트에서 커플 링을 낮추는 방법에 대한 경험을 공유하십시오. 안녕!
x0 z1

3

여기에는 총알이 없지만 확인할 사항이 많습니다.

  • 실제로 스키마 구성에서 디버그 구성을 사용하고 있는지 확인하십시오.디버그 구성을 사용하는 Xcode Scheme Editor

  • 매트의 조언에 따라 증분 빌드와 전체 모듈을 사용하는 방법은 아래를 참조하십시오. 또한 디버그 빌드에 대한 최적화 레벨 이 없는지 확인하십시오 . 증분 빌드를 표시하는 Xcode 빌드 설정

  • RxSwift와 같은 유형 유추 무거운 프레임 워크를 사용하는 경우 명시적인 유형 주석을 추가하면 빌드 시간이 단축 될 수 있습니다.

  • 프로젝트가 매우 큰 경우 소스 파일의 논리 그룹을 프레임 워크로 리팩토링하는 것을 고려할 수 있지만 원하는 것보다 너무 과감한 변경이있을 수 있습니다.

프로젝트에 대해 좀 더 구체적인 내용을 제공하면 도움이 될 수 있습니다. 라이브러리를 정적으로 연결하고 있습니까? 프레임 워크 또는 앱 대상입니까? 당신은 얼마나 크고 빠른 버전을 사용하고 있습니까? 린 터나 코드 생성과 같이 때때로 건너 뛸 수있는 사용자 지정 빌드 단계가 있습니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.