- 세션보면서 정리한 내용입니다. 해석이 잘못된 경우가 있을수있으니 발견하시면 댓글로 남겨주시면 감사하겠습니다🙏🏻
https://developer.apple.com/videos/play/wwdc2018/415/
관련내용
- Xcode가 어떻게 빌드하는 과정을 자동화하는지 ,
- 어떻게 나누어진파일들, 또는 파일들의위치가변경되도 호출되어질수있는지,
- clang, swiftc, linker 가어떻게 같이 작동하는지
👍요약
- xcode는 커맨드라인으로실행되는데 수천개의명령어가있고, 이를 xcodebuild가 자동화해준다.
- 👍xcode10부터는 incremental build ( 증분빌드 ) 라는 개념이 생겼다.
- 이는, 빌드정보들을 저장하여, 변화가있을때만 리빌드하는 개념이다.
- 가능한이유는, 각 작업들은 hash값들을 가지고있고, 빌드시스템은 이전빌드와 현재의 정보들을 비교하여 구현해낸다.
- 👍Clang은 각 호출한 헤더들을 헤더맵을 만들어냄으로써 호출이가능해진다.
- 다양한파일들에서 같은 헤더들을 호출하면 코드들이 방대해지는데, 이를 Clang Module을 통하여 한번만 만들어지도록 하여 더 빠르게 실행되도록한다.
- 👍swift타깃은 header파일이없기때문에, 컴파일할때 추가적인작업이필요하다. 즉, 사용된타입을 하나의타깃안에서 모두찾도록한다. 하지만 xcode10부터는 이러한 파일들을 최대한 공통적으로 그룹으로만들어, 오버헤드를 줄이도록 개선했다.
- 즉, swift는 objective-c보다 컴파일이 느릴수밖에없다
빌드시스템
- 다양한작업들의실행은 커맨드라인으로 통해 실행된다
- Clang, LD, AC tool, IB tool, Code sign,

- 이러한 실행들은 특정한arguments, configuration에 지정된순서로 실행되어져야한다
- xcode build system은 이러한 ㅈ가업들을 자동하해준다.
- 수천개이상이될텐데, 이러한 코드들을직접 타이핑하는건싫자나~
- 아래와같이 하나로 쏵~실행가능!

- 아래와같이 이어진다.
- swift, objective-c, storyboard, xcassets,

- 의존성정보로부터 실행순서들이결정되어진다.
- 즉, PetViewController.m을파일을 인풋으로 컴파일하여, PetViewController.o 파일로만들고, 링커가 이파일들을 인풋으로받아, Petwall 결과물을만들고,
- petwall인풋은 petWall.app 번들로 만들어진다.
- 아래와같이 병렬적으로실행되면서 마지막에 링커가받는다.
- 각 실행들은 의존성ㅇ을갖는다.

- 각 실행들은 의존성ㅇ을갖는다.
빌드과정
- 우선, build description을 받는다.
- parse하고, 프로젝트안에 있는 파일들, target, 의존성관계, build setting을 계산하고,
- 아래와같이 트리과정이생긴다

- low-level engin 은 위의 그래프를 아래와같이 의존성, 순서들을찾고, 어떤것을실행하고, 어떤것을병렬적으로처리할지한다.
- 이러한것은 llbuild라는 오픈소스로 운영된다
- Clang은 objective-C 파일을 object(.o)파일로만들뿐만아니라, .d라는 어떤헤더파일들이 포함되어있는지 리스트가담긴. 것을생성한다!
- 이는, 다음에빌드할때, 파일에 헤더파일의변화가있을경우 재컴파일하도록 하게해준다.
- 앱이커질수록 파일들도많아지고, 매번 빌드할때마다 모든 컴파일하고싶지는않을것이다 - 오래걸리니까,
- 그래서대신 빌드시스템은 몇개의 subset만실행할수도있다
- 이전에빌드했을때, 달라진점만 빌드하도록!
- 이를👍 incremental build 라한다! - 증분빌드
- 그래서, 각 정확한의존성을갖는것이 중요하다!

- 그래서, 어떻게 변화가 증분빌드에영향을주는지보자
- 또한 어떻게 변화를감지할까?
- 각작업들은 특정 singature를가진다 - 관련정보들을 바탕으로 계산된 해시종류로,
- 그래서 빌드시스템은 이러한 이전의 singature와 현재 signature를 추적한다.
- 그러므로, 다르면 다시 리빌드한다.
- 그럼어떻게 내가 이러한 빌드시스템에도움을줄수있을까?
- 작업순서실행을 고려하지말라, 이것은 빌드시스템이할일이니까,
- 대신우리는 의존성을 생각할수있다.
- Buit in 단계에서 asset, storyboard, 등등 파일들을 지정해줄수있다.

-
- Target dependencies 를 지정한다.
- xcode10부터는 이를통해 병렬적으로? 수행잘되도록해주다.
- 하지만, 따로 run script를 작성하면, 이러한 병렬적 실행전에 우선적으로 runscript가실행된다.
- Target dependencies 를 지정한다.
-
- 라이브러리들을 지정해준다.
-
- 빌드phase에 잘지정해준다.
- 하지만 빌드시스템은 더 나은방법을생각한다면 무시되어질수있다.
- 빌드phase에 잘지정해준다.
-
- build parel 를 체크하도록함으로써 병렬적으로실행하도록 하게하라.
- 체크해재한다면 명시된순서대로 하나하나씩실행하게된다
- build parel 를 체크하도록함으로써 병렬적으로실행하도록 하게하라.
- 마지막으로는 개발자가 script를 작성하는것이다.
- input, output 지정
- 이러한경우, 빌드시스템은 불필요하게리빌드하지않는다.

- 정학한의존성정보들은 빌드시스템이 더 병렬적으로, 더일관된결괄르줄것이다
- 만약 모든코어를 잘활용할수있도록하기위해서는 Building Faster in xcode session을참고하셈!
Clang
- apple의 공식적인 C컴파일러다. C,C++, Objective
- 컴파일과정
- api를접근하고싶다면, ios로부터, 구현을, 헤더파일을 추가해야한다.
- 헤더파일은 약속이다. 구현된어떠한파일이존재할것이라고
- 만약그렇지않다면, 컴파일타임때 오류를발생시키지않는다?
- 대신 링크타임때 오류를발생시킨다.
- 파일,헤더들을 위치를 변경시켜도 문제없이 빌드가가능하다.
- 그럼 어떻게 컴파일러는 헤더파일을찾을까?
- import 헤더를 하면, 헤더맵이 생성? 사용되어진다. 이것은 Xcodebuildsystem에의해, 헤더파일이어디있는지찾기위해.
- 헤더맵은 프레임워크이름을 추가시키고,
- 항상 헤더파일을 프로젝트에 추가시켜랑, -import 할때, 프레임워크이름도붙여라.
- 그리고이름은 유니크하게지어라 .그렇지않으면 다른헤더를 가리게된다
- 시스템헤더파일은 헤더맵을 만들지않는다. 왜냐하면 이미유니크하기때문이고. 그래서 설치된sdk에서 경로를 찾는다. 다양한경로를찾아보고, 그래도없다면 더이상찾지않는다.
- import 헤더를 하면, 헤더맵이 생성? 사용되어진다. 이것은 Xcodebuildsystem에의해, 헤더파일이어디있는지찾기위해.
- 여튼, 그런 헤더파일을 호출하고나면, 엄청많은 코드들이생성되어진다. 즉, 같은 헤더를 다른파일에서 가각호출하면 이러한코드들이엄청방대해진다.
- 하지만, Clang modules은 프레임워크안의 헤더들을 오직한번만 찾고,파싱하게한다. 그리고이러한정보들을 디스크에 저장하고, 캐싱한다그럼으로써 빌드시간이빨리된다!
- 시스템프레임워크들은 이렇게 찾아지고, 캐시되어진다.
- 우리가만든 프레임워크는 어떻게 찾고 어떻게 빌ㄷ할까?
- 여기서 Clang의 Virtual File system이 소개된다
- 컴파일러는 가상의 추상적으로 파일을만들어, 헤더와모듈을 생성해낸다.
swift compile
- swift는 objective-c와 달리 헤더파일을 작성하지않는다 .
- 이덕분에 초보자들이시작하기좋다.
- 하지만 이 덕분에 컴파일러는 추가적인 book-keeping 을 한다.
- 아래와같은 4가지작업을한다.

- 우선, 작성된코드안에 다른 코드에서 생성된 타입을 사용하는 타입이있는지 확인한다(load and parse)
- 즉 하나의 swift파일을 컴파일하기위해서 target안에 작성된 모든코드들을 탐색한다
- xcode9에서는 이를 병렬적으로 모두탐색했다
- xcode10부터는 이러한오버헤드를 줄였다
- 각파일들을 최대한공유할수있도록 그룹으로나누었다
- 그리고 각그룹별로만 모두탐색하도록하게했다.
- 즉그룹별 상대적으로덜관련있어야 더 빌드속도가빨라진다
- swift코드뿐만아니라 objective-c를 사용할때는 Clang을 사용한다.
- swift는 objective-c가 사용할수있도록 Objective-C header 인터페이스를 생성한다.
- 다른 swift타겟에서도 사용될수있도록하기위해 Clang’s의 모듈과같은개념을 빌드한다.
- 즉, import를 사용해야한다. ( XCTest에서 테스트코드작성시, swift모듈을 import해야사용할수있다.
- .swiftmodule을통하여 선언부를확인할수있게된다
- 바이너리형태이고, 함수, 디버깅을위해 private도 포함되어있다.
- 증분빌드( Incremental build ) 를하기위해, swiftc컴파일러는 부분적으로 .swiftmoudle 파일을만들고, 이를 나중에 전체 moudle로 합친다 또한 objective C Header를 만들어낸다.
- 이것은 링커가 하나의 실행가능한파일로만들기위한방법과비슷하다

링커
- 마지막작업으로, 두개의컴파일러에의해 만들어진 두 object file을 하나의 실행파일로만들기위한작업을한다.
- 두개의파일을 취하는데, Object file과, 라이브러리 ( .dylib, .tbd, .a, static archive )
- 링커단계에서는 코드를생성하거나 삭제하지않는다. 오직 카피, 분리할뿐이다
- symbol
- 코드,데이터의 fragment를 위한이름이다
- 코드들은 다른 symbols를 참조할수있고,
- 이 symols는 링커가어떻게행동할지를 명시할수있는 속성을가지고있다.
- 예로, Weak symbols
- object file
- 컴파일되었지만, 실행가능한파일이이아니다.
- 라이브러리
- target의 부분으로써 build되어진것이 아닌 symbol 명시한다
- Dylibs - 다이나믹라이브러리
- TBDs - Text Based Dylibs
- mapKit,이나 이러한 프레임워크는 코드가굉장히방대해서, 모두다 넣기보다는, body를지우고, name만남긴형태로사용한다.
- static archive
- .o 파일들의 컬렉션이다 - AR?
- 링커과정
- object file들은 이미컴파일과정에서 실제코드이름이아닌, mangle된 symbol로 변형되있다.
- __Text영역에 string과 실행가능한 영역으로분리하고, 각각에맞는 코드들을 넣는다. 각 mangled symbol들을 각 다른 파일에서 찾아, 같은 symbol이 있따면, 그에관련한 코드들을 또 집어넣어준다.
- 찾는과정에서 링커파일에 없는 symbol들은 추가하지않는다.
- 그리고 .tbd파일에서도 찾으며, .tbd파일관련 함수들은 모두 고대로 복사하지않는다. 대신 어느정도 유추할수있도록만 복사한다.
- 글로벌변수들을 _Data영역에저장한다.
- __LINKEDIT 에는 metadata로, 링커툴이 Opertaing system을 위한 정보를 남기기위해 사용하는, ( dynamic linker가 런타임때 고치기위한 ? )

'WWDC' 카테고리의 다른 글
WWDC 18 - Core Data Best Practices (0) | 2021.07.02 |
---|---|
WWDC 17 - Efficient Interactions with Frameworks (0) | 2021.06.30 |
WWDC 15 - Optimizing Swift Performance (0) | 2021.06.27 |
WWDC 13 - What’s new with Multitasking (0) | 2021.06.27 |
WWDC 16 - What's New in UICollectionView in iOS 10 (0) | 2021.06.26 |