스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
명시적으로 빌드된 모듈 쉽게 이해하기
명시적으로 빌드된 모듈을 통해 Xcode 16에서 빌드가 어떻게 바뀌었는지 확인해 보세요. 코드를 빌드하는 데 모듈이 사용되는 방식과 명시적으로 빌드된 모듈이 컴파일 작업의 투명성을 향상하는 방법 그리고 여러 대상에서 모듈을 공유하여 빌드를 최적화하는 방법을 공유합니다.
챕터
- 0:00 - Introduction
- 0:17 - Agenda
- 0:34 - What are modules?
- 3:57 - Using modules
- 8:37 - Module build log
- 11:28 - Optimize your build
- 14:45 - Wrap up
리소스
관련 비디오
WWDC22
-
다운로드
안녕하세요 오늘 저는 Swift와 Clang 모듈이 Xcode에서 구축되는 새로운 방식인 명시적으로 빌드된 모듈에 대해 소개하고 설명할 예정입니다 모듈이란 무엇인지에 대한 개요를 시작으로 모듈을 사용하여 코드를 구축하는 방법을 설명하고 새로운 Xcode에서 보게 될 차이점이 무엇인지 알아보며 마지막으로 이미 구축된 모듈을 최대한 재사용하여 빌드를 최적화하는 방법을 살펴봅니다
기본적으로 모듈은 코드 배포의 단위이며 라이브러리나 프레임워크의 인터페이스를 설명해 줍니다 Swift 대상에는 모듈을 구성하는 여러 Swift 파일이 포함되고 일반적으로 단일 대상이나 프레임워크의 모든 Swift 소스 파일은 동일한 모듈에 포함됩니다 모듈의 인터페이스는 Swift에 액세스 지정자로 명시적 표시되요 클래스와 해당 변수가 public으로 표시되어 임포터에게 보여집니다
모듈은 다른 모듈을 가져올 수도 있으며 전체 프로젝트에서 비순환 모듈 그래프를 형성합니다 Swift 컴파일러는 사용자가 작성한 외부 인터페이스를 가져와 인터페이스만 포함된 텍스트 형식의 .swiftinterface 파일로 요약해요
Objective-C에 있는 모듈은 다르게 표현됩니다 Swift와 달리 C 언어 제품군에서는 모듈의 인터페이스가 수기로 작성됩니다
잘 알려진 헤더 개념으로 시작하여 헤더에서 모듈이 구성되는 방식을 설명해 주는 모듈 맵이라는 파일을 옆에 추가합니다 화면은 UIKit 모듈의 예입니다 UIKit의 헤더로 시작한 다음 UIKit 모듈 맵을 추가합니다 이 모듈 맵은 UIKit 모듈에 대한 여러 정보를 컴파일러에 전달해요 먼저 이것은 프레임워크 모듈이고 이름이 UIKit이라는 것을 나타내요 이 이름이 @import가 작동하도록 해 주며 소스 코드 자체는 이름을 정의하지 않습니다
그런 다음 UIKit.h에는 이 모듈에 구성된 모든 헤더가 포함됩니다 마지막으로 이 모듈이 가져오는 모든 모듈은 UIKit을 가져오는 코드에서 사용할 수 있습니다
이름이 지정된 모듈 가져오기가 코드에 포함되거나 모듈에 속한 헤더를 포함할 때마다 모듈이 사용됩니다 다음은 ResearchKit 프로젝트예요 여기에는 모듈을 사용하는 Swift와 Objective-C 코드가 포함되죠
ResearchKit의 Swift 소스 파일을 살펴보겠습니다 먼저 Swift 모듈인 SwiftUI를 가져온 후 ResearchKit 모듈의 가져오기를 진행합니다 프로젝트 자체에서 Objective-C로 구현된 Clang 모듈입니다 다른 탭에는 Objective-C 파일이 있습니다 일부 프로젝트 헤더 가져오기 UIKit 가져오기가 포함되며 Clang이 모듈 가져오기로 변환하는 SDK 헤더도 포함되어 있습니다
모듈을 사용하면 컴파일러가 다양한 소스 파일 전반에서 인터페이스의 구문 분석을 공유할 수 있습니다 각 모듈을 독립적으로 컴파일링해 컴파일러가 프로젝트 소스를 컴파일할 때 읽을 수 있도록 바이너리 파일로 변환하고 참조마다 모듈 공용 인터페이스를 가져오는 식으로 작업이 진행되요 Swift에서 이 컴파일된 형식이 *.swiftmodule 파일로 표시되며 Clang에서는 *.pcm이나 사전 컴파일된 모듈 파일로 됩니다
하지만 이 재사용이 가능하려면 해당 모듈을 먼저 찾아서 컴파일해야 합니다 어떻게 이 작업이 이뤄질까요?
컴파일러가 가져오기를 발견하면 먼저 해당 가져오기가 참조하는 모듈을 발견하고 해당 모듈의 컴파일된 표현을 가져옵니다 컴파일러가 @import UIKit을 식별하면 먼저 SDK에서 UIKit의 모듈 맵을 찾습니다 이제 UIKit 모듈에 대해 알아봤으니 UIKit에서 컴파일된 .pcm 파일을 찾아야 합니다 하지만 해당 파일이 이미 존재하지 않으면 어떻하죠?
모듈을 만드는 두 가지 개괄적인 방법과 Xcode 16의 차이점을 알아봅니다 먼저 묵시적으로 빌드된 모듈이며 Xcode의 다른 부분에서는 이 모듈의 존재가 알려지지 않아도 컴파일러들이 서로 조정하며 모듈 빌드를 관리합니다 Swift와 Clang이 도입된 이후 모듈 빌드가 진행되어 온 방식이죠 프로젝트에 Swift, C Objective-C 코드가 포함되면 묵시적 빌드 모듈을 사용하지만 빌드에는 종종 여러 장기적인 실행 작업이 포함됩니다 각 행은 Xcode가 빌드 작업을 수행할 수 있는 개별 실행 라인을 나타냅니다 빌드 시스템이 컴파일 작업을 시작하고 개별 컴파일러가 묵시적 방식으로 발견하고 먼저 도달한 경우 모듈을 빌드하거나 진행하면서 이미 존재하는 모듈을 로드합니다
타임라인 뷰에는 다음과 같이 표시될 수 있으며 빌드 시작 부분의 컴파일 작업이 끝부분 작업보다 더 오래 걸립니다
묵시적으로 빌드된 모듈을 사용하면 묵시적으로 모듈을 빌드하는 한 번의 컴파일 작업으로 끝내면서 또 다른 작업이 해당 모듈을 필요로 하여 중단되고 빌드되기를 기다릴 수 있습니다 이러한 상황이 빌드의 많은 부분 전반에 걸쳐 발생할 수 있습니다 Xcode 16은 명시적으로 빌드된 모듈을 사용하여 Xcode가 컴파일러와 조정을 통해 모듈을 발견, 빌드하도록 변경하죠 명시적으로 빌드된 모듈은 묵시적 모듈 빌드 작업을 진행하며 명시적 빌드 시스템 작업으로 이를 전환합니다
이렇게 하기 위해 Xcode는 각 소스 파일의 컴파일을 각 세 단계로 나눕니다 스캔, 모듈 빌드 최종적으로 원본 코드 빌드입니다
Xcode는 각 소스 파일 검사부터 시작하여 전체 프로젝트에 대한 모듈 그래프를 구성하고 대상 전체에서 모듈을 공유합니다 모듈 그래프를 구성하면서 모듈 컴파일 작업 전달을 시작할 수도 있습니다 다음은 빌드 로그의 명시적인 작업이며 필요한 컴파일된 모듈을 직접 제공받을 수 있습니다 마지막은 원래 컴파일 작업의 실행 단계이며 필요한 컴파일된 모듈을 추가하도록 수정된 후 진행됩니다
명시적으로 빌드된 모듈의 경우 타임라인 뷰에 명시적인 스캔 작업 모듈 컴파일 작업 원본 소스 파일 작업이 포함됩니다 그럼에도 시간은 크게 단축되었죠
모듈의 존재를 인식하는 빌드 시스템의 이점은 이제 실행 준비가 안된 작업으로 실행 라인을 채우는 것을 방지할 수 있다는 것입니다 대신 모듈이 준비될 때까지 작업을 실행하지 않고 기다립니다 이렇게 하면 빌드 시스템이 사용 가능한 실행 라인을 효과적으로 사용할 수 있습니다
모듈 빌드에 대한 이 접근 방식을 채택하면 몇 가지 이점이 있습니다 첫째로 해당 빌드를 더 신뢰할 수 있습니다 정확한 종속성과 빌드 시스템에 노출된 확정적인 빌드 그래프를 사용하여 컴파일러가 매번 같은 방식으로 실행되고 빌드 실패가 발생하면 실패한 작업만 다시 실행하여 재현하면 됩니다 어디에도 묵시적인 상태가 유지되지 않습니다 즉 이제 결함이 없는 빌드가 모듈을 다시 빌드합니다 이로써 더 효율적인 빌드가 가능합니다 이제 빌드 시스템이 모듈 그래프에 대해 완전히 알아서 모듈이 빌드될 때까지 기다리며 컴파일 작업으로 실행 라인이 중단되지 않도록 정보에 기반한 더 나은 일정 옵션을 만들 수 있습니다 모듈 빌드를 조정하는 빌드 시스템의 또 다른 이점은 Xcode에서 디버깅할 때 디버거에 Swift 모듈을 전달한다는 것입니다
프로젝트가 묵시적으로 빌드된 모듈을 사용하여 구축될 경우 Xcode 빌드와 디버거에는 완전 별개 모듈 그래프가 포함되요 명시적으로 빌드된 모듈을 사용해 디버거에서 이미 빌드된 모듈을 재사용할 수 있습니다 이렇게 하면 디버거가 Swift 유형에 대해 알아야 할 때 모듈을 다시 빌드하는 일을 피할 수 있습니다 예를 들어 ‘p’ 또는 ‘po’를 사용한 표현을 평가하는 경우예요 명시적 빌드 모듈은 빌드 로그에 작업 표시 방법에도 영향을 미쳐요 Xcode 16에서 명시적 빌드 모듈은 모든 C, Objective-C 코드에 사용되며 Swift 미리보기로 활성화할 수 있습니다 먼저 Swift의 명시적으로 빌드된 모듈을 활성화하기 위해 프로젝트 탐색기에서 ResearchKit 프로젝트를 선택해요
‘Build Settings’를 선택하고 필터 상자에 ‘explicitly built’를 입력해요
‘Explicitly Built Modules’ 설정을 선택해 ‘Yes’로 설정합니다
이제 명시적으로 빌드된 모듈이 Clang과 Swift에서 활성화되었으니 빌드를 시작할 수 있어요
빌드 로그에는 많은 스캔 작업이 포함됩니다 프로젝트의 각 소스 파일에 대해 한 번 실행되며 빌드 시스템의 모듈 가져오기 그래프를 생성해요 기본 제공 작업이며 새 프로세스를 생성하지 않습니다 이렇게 하면 빌드 시스템이 스캔되는 소스 파일 간의 정보를 캐싱할 수 있습니다
두 번째 새로운 작업은 컴파일 모듈 작업입니다 이 작업은 특정 프로젝트나 대상에 국한되어 있지 않습니다 대신 이는 상위 수준의 작업이며 대상 간에 공유될 수 있습니다 이 경우 빌드 시스템은 작업별로 각 컴파일러 프로세스를 생성해요 이 작업은 특정 모듈을 컴파일된 모듈 파일로 빌드합니다 묵시적으로 빌드된 모듈의 정상적인 컴파일 도중에 발생했던 작업이며 이제 분리되었습니다 모듈을 만드는 동안 식별된 모든 진단이 여기에 첨부되며 어떤 소스 파일이 먼저 모듈을 빌드했는지에 영향을 받지 않아요 같은 모듈이 수차례 빌드되는 것을 아실 수 있을 겁니다 이 빌드에서는 UIKit 모듈이 여러 번 나타납니다 그 이유는 일부 빌드 설정이 다른 대상에서 모듈의 다양한 변형을 빌드해야 할 수 있기 때문입니다 이 빌드에는 두 Swift 모듈 변형과 네 개의 Clang 모듈 변형이 있어요
두 개를 자세히 살펴보면 Xcode에 다른 해시가 표시됩니다 이 해시는 이 모듈 변형을 빌드하는 데 필요한 명령줄 인수 모음을 나타냅니다 이러한 플래그는 흔히 언어 표준 기능 매크로나 포함 경로의 차이 같은 것입니다 자주 접하게 될 가능성이 있으며 묵시적 빌드 모듈에서도 발생했고 그러나 모듈 빌드가 빌드 시스템에 노출되지 않아 더 알아차리기 어려웠습니다 컴파일러가 스캔 과정에서 이 인수 목록을 최적화하여 모듈 빌드에 영향을 미치지 않는 항목을 제거합니다 비사용 헤더 검색 경로 등을 예로 들 수 있어요 ResearchKit으로 돌아가서 추가 변형을 삭제해 보겠습니다 먼저 프로젝트에서 만든 모듈의 추가 정보를 수집하고 싶습니다
빌드 폴더를 정리해 프로젝트의 모든 모듈을 다시 빌드하겠습니다
‘Product’, ‘Perform Action’ ‘Build with Timing Summary’를 통해 빌드 성능에 대한 추가 정보를 수집합니다 여러 모듈 변형은 호환되지 않는 빌드 설정이 있는 다른 소스 파일로 인해 발생합니다 예를 들어 C 소스 파일과 Objective-C 소스 파일은 일부 모듈을 매우 다르게 구문 분석할 수 있습니다 불필요한 모듈 변형은 빌드에서 수행해야 하는 추가 작업을 야기합니다
일부 일반적인 모듈 변형 소스는 추가 전처리기 매크로 추가 언어 모드, 예를 들어 단일 C 파일이 Objective-C와 혼합된 경우 또는 언어 버전 예컨대 Objective-C를 C17 등의 최신 C 버전과 함께 사용하는 경우 Automatic Reference Counting 비활성화가 해당됩니다 빌드가 완료되었고 필터로 이동해 ‘modules report’를 입력합니다
Clang 모듈 보고서를 선택하면 UIKit의 변형 두 개와 다른 많은 모듈이 나열됩니다
Swift 모듈 보고서를 선택하면 두 개의 변형이 표시됩니다 여기에 나온 내용이 앞서 빌드 로그에서 확인했던 UIKit 네 가지 변형을 뒷받침합니다 변형 개수를 줄이려면 일반적으로 이 변형이 발생하는 데 영향을 주는 빌드 설정을 점검해요 프로젝트 탐색기에서 ResearchKit을 선택하고 필터 상자에 ‘macros’를 입력해 추가 매크로 설정을 확인합니다 프로젝트 수준에서 확인되는 것이 없으므로 ResearchKit 대상의 빌드 설정으로 이동합니다
이 대상에는 다른 대상에는 없는 ENABLE_FEATURE 매크로가 있습니다
‘Levels’ 모드를 선택해 동시에 프로젝트 레벨 설정도 확인합니다
대상에서 이 매크로를 제거하고 ResearchKit 프로젝트에 배치해요
‘Product’, ‘Clean Build Folder’ ‘Build with Timing Summary’를 재선택해요
이번에는 빌드 로그에 UIKit 변형 세 개만 표시합니다 하나는 Objective-C용이고 두 개는 Swift용입니다 하나는 Clang 모듈용이고 다른 하나는 Swift 모듈용입니다
프로젝트 설정을 통합하여 이러한 개별 그래프를 가져와 하나로 합칠 수 있습니다 일반적으로 프로젝트에서 빌드 설정을 가능한 넓게 적용하는 것이 타당합니다 대상 수준에서 언어 표준을 설정하는 대신 프로젝트나 작업 공간 수준 이상으로 올려야 합니다 그러면 모듈을 소스 파일 간에 가능한 한 많이 공유할 수 있어요 이것이 바로 명시적으로 빌드된 모듈입니다
이 시간을 통해 기억해야 할 주요 내용입니다 명시적 빌드 모듈은 빌드 시스템이 모듈 빌드를 제어하도록 합니다 이제 빌드 로그가 다르게 표시되지만 모듈 빌드의 컴파일 시간이 자체 작업으로 표시되고 컴파일 작업에는 포함되지 않습니다 빌드되는 모듈 변형의 개수를 줄이려면 프로젝트 전반에 걸쳐 일관성 있게 설정합니다 주어진 소스 파일에 따라 빌드된 모듈을 대상 간에 공유할 수 있죠 시청해 주셔서 감사합니다
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.