Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] Xcode Build System (빌드 시스템, Incremental Build System) 본문

iOS 응용 (swift)

[iOS - swift] Xcode Build System (빌드 시스템, Incremental Build System)

jake-kim 2023. 4. 13. 01:41

빌드 시스템

  • Xcode에서 빌드 (cmd + R)을 하면 아래와 같은 플로우를 거쳐서 빌드가 완성
    • 단, Xcode10 부터는 *Incremental Build System를 사용하여 빌드 속도가 개선 (아래에서 설명)

https://www.vadimbulavin.com/xcode-build-system/

1. Preprocessor (전처리기)

  • 컴파일타임 전보다 전처리기가 먼저 동작하여 컴파일 직전에 전처리기에 의해서 컴파일할 소스코드가 정해짐
  • Xcode > Build Settings > Active Comiplation Conditions에서 설정
    • 이름이 Active Comiplation Conditions인 이유는 말 그대로 컴파일전 조건을 미리 정해준다는 의미

2. Compiler (컴파일러)

  • 소스코드(swift)를 어셈블리어로 변경
    • 어셈블리어: 하드웨어를 직접 제어할 수 있는 저수준의 언어 (기계어는 아니고 사람이 이해할 수 있을만한 텍스트 형식의 언어)

ex) 어셈블리어

https://ko.wikipedia.org/wiki/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4

  • 컴파일러는 소스코드를 어셈블리어로 변경할 뿐만 아니라 symbol table도 생성
    • symbol table: property, function, class 이름을 각각 저장하고 보관

3. Assembler (어셈블러)

  • Object 파일로 변경 (기계어 코드로 변경)
  • Xcode에서는 대표적으로 .o 파일이 있고 이를 Mach-O 타입이라고 명칭
    • 오브젝트 파일(.o)
    • 동적 라이브러리(.dylib)
    • 정적 라이브러리(.a)
    • 번들(.bundle)
  • 직접 확인해보기
    • 빌드 후에 DerivedData로 이동
cd ~/Library/Developer/Xcode/DerivedData
  • 프로젝트 이름으로 된 폴더를 찾고, Build 폴더 안에서 쭉 들어가면 .o파일이 존재

  • file 명령어로 Mach-O 타입 확인
    • 여기서 핵심) 어셈블러 단계에서 오브젝트 파일이 생성되는데, 이 파일의 형태는 Mach-O이고 위치는 로컬 폴더 DerivedData 하위에 존재
    • DerivedData 하위에 이런 정보를 저장해놓고 캐싱하여 빌드
% file Alamofire.o
Alamofire.o: Mach-O 64-bit object arm64
  • 어셈블러에의해 만들어진 오브젝트 파일을 호기심으로 읽고 싶은 경우?
    • hex코드로 읽기가 가능
% hexdump Alamofire.o

044c9e0 6663 3155 005f 245f 3973 6c41 6d61 666f
044c9f0 7269 3165 4437 7461 5361 7274 6165 526d
044ca00 7165 6575 7473 3043 7238 7365 6f70 736e
044ca10 4365 3530 7375 6e69 3267 6e6f 7336 7274
044ca20 6165 416d 5843 7844 535f 316f 4f37 5f53
044ca30 6964 7073 7461 6863 715f 6575 6575 7943
044ca40 4341 4330 5630 5f79 3631 6553 6972 6c61
044ca50 7a69 6465 624f 656a 7463 7a51 4141 4137
044ca60 4546 7272 726f 474f 634b 4174 3041 4365
...

4. Linker

  • 링커란 위에서 만든 오브젝트 파일과 라이브러리들을 연결시켜주어 실행파일로 만드는 것
  • 만약 static framework이면 링커가 실행 파일 안에 static framework를 넣고, dynamic framework이면 링커가 실행 파일에 프레임워크를 포함시키지 않으며 오브젝트 파일을 실행파일로 변환
    • static framework와 dynamic framework의 개념은 이전 포스팅 글 참고
  • 링커의 이러한 역할때문에, static framework를 쓸때 의존 관계에 있어서 코드 중복에 유의해야함
    • static1, static2 -> static (ok)
    • static1, dynamic1 -> static (ok)
    • dynamic1, dynamic2 -> static (코드중복발생)

* static은 링커 타임에 결정되므로 여러개의 static framework가 하나의 static을 의존하더라도 링커타임에 체크하기에 때문에 하나만 만듦
* dynamic은 링커타임이 아닌 런타임에 코드를 참조하면서 이때 복사해버리기 때문에 static이 두 번 참조되면 2개의 동일한 static 프레임워크가 생성  (static1과 dynamic1 각각 static을 참조하는 경우는 이미 static1이 참조하여 링커타임에 생성되고, dynamic1이 런타임에 참조할 경우 static1이 만든 파일을 사용하기 때문에 중복x)

5. Loader

  • 디스크에 만들어진 실행 파일을 메모리로 로드하는 작업

번외) 빌드 캐싱 (Incremental Build System)

  • 소스코드 변경이 없으면 이전에 생성된 object 파일과 라이브러리를 그대로 사용하기 때문에 재빌드하지 않음
  • 소스코드 변경이 있다면 변경된 부분의 의존성 그래프를 확인하고, 변경된 파일이나 의존하는 파일만 다시 빌드를 수행
    • 이전 빌드에서 생성된 오브젝트 파일과 프레임워크를 사용하여 새로운 오브젝트 파일 생성
    • 변경된 파일을 빌드한 후 Xcode는 이전 빌드에서 생성된 프레임워크와 새로 빌드한 오브젝트 파일을 링킹
    • 모든 오브젝트 파일이 링킹되면 실행 파일을 생성

* 참고

https://eunjin3786.tistory.com/323

https://ko.wikipedia.org/wiki/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4

https://www.vadimbulavin.com/xcode-build-system/

Comments