티스토리 뷰

🍏/iOS

[iOS] XCode Build System 이해하기

eungding 2021. 2. 15. 23:28
반응형

Understanding Xcode Build System  이라는 포스팅을 읽었는데

대학생때 배웠던 Compile Process (전처리기 -> 컴파일러 -> 어셈블러 -> 링커) 에

여기저기서 주워들은(?) llbuild, SIL, clang 등 Xcode Build 관련 용어들이 단계별로 들어가있었습니다.

 

신기해서 기록합니다 ✏️

저의 번역말고 원글을 읽어보시는 것을 추천드립니다. 

 

 

이렇게 다섯단계인데 한 단계씩 살펴보겠습니다.

 

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

 

 

[1] 전처리기 Preprocessor

 

전처리 단계의 목적은 컴파일러에 제공할 수 있는 방식으로 프로그램을 변환하는 것입니다. 

매크로(macro)를 정의로 대체하고 

dependencies를 발견하며 전처리기 지시문(preprocessor directives)를 해결합니다.

 

Swift 컴파일러에는 전처리기가 없다는 점을 고려하면 Swift 프로젝트에서 매크로를 정의할 수 없습니다.

그럼에도 불구하고 Xcode 빌드 시스템은 이를 부분적으로 보상하고 

Build Settings에서 설정할 수 있는 Active Compilation Conditions을 통해

전처리를 수행합니다. 

 

Active Compilation Conditions

 

(참고: [Swift] 전처리문 (#if DEBUG, #if os) )

 

Xcode는 하위 레벨 빌드 시스템 llbuild를 통해 종속성(dependencies)을 해결합니다 . 

llbuild는 low-level build system의 약자입니다. 

 

 

[2] 컴파일러 Compiler

 

고수준언어인 Swift , Objective-C, C , C ++ 코드를

저수준언어인 어셈블리어로 변환하는 단계입니다.

 

Xcode는 두 가지 다른 컴파일러를 사용합니다.

하나는 Swift 용인 swiftc 

다른 하나는 C languages family (Objective-C , Objective-C ++ , C , C ++)용인 Clang 

입니다. 

 

 

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

 

XCode > Build Settings에 보면

Swift Compiler 설정이랑 

Apple Clang 설정이 각각 있는 것을 볼 수 있습니다. 

 

for Swift

 

for C family

 

컴파일러는 2가지 파트로 구성됩니다. front end, back end 입니다. 

 

front end 파트는 source program을 별도의 조각으로 나눕니다. (어떤 semantic이나 type 정보가 없이)

그리고 문법 구조 (grammatical structure)를 준수할 것을 강요합니다. 

 

그 다음 컴파일러는 이 구조로  source program의 중간 표현(intermediate representation)을 생성합니다.

또한  source program에 대한 정보를 수집 하는 symbol table을 작성하고 관리합니다 .

(symbol은 code나 data 조각의 이름입니다.) 

 

symbol table은 variables, functions, classes의 이름을 저장하고

각각의 symbol은 데이터의 특정 조각에 매핑됩니다. 

 

swift compiler의 경우,  intermediate representation은 Swift Intermediate Language (SIL) 이라고 부릅니다. 

SIL은 코드의 추가 분석 및 최적화에 사용됩니다.

그리고 SIL은 LLVM Intermediate Representation 으로 한 번 더 변환됩니다.

 

back end 단계에서 Intermediate Representation은 assembly code로 변환됩니다. 

 

 

[3] 어셈블러 Assembler

 

Assembler는 human-readable한 assembly code를 재배치가능한 (relocatable)  machine code로 바꿉니다.

이때 Mach-O 파일을 생성합니다. Mach-O파일은 코드와 데이터의 모음입니다. 

 

machine code와 Mach-O 파일에 대해서 좀 더 살펴봅시다.

 

machine code는 CPU에서 직접 실행할 수있는 명령들의 집합을 나타내는 numeric language입니다.

이것을 재배치 가능하다고 (relocatable) 하는 이유는

object file이 어느 address space에 있는지 상관없이 명령이 해당 공간에 대해 상대적으로 실행되기 때문입니다. 

 

Mach-O 파일은 iOS와 MacOS에서 쓰이는 특정한 파일 포맷입니다.

object files, 실행 파일, 라이브러리에 이 파일 포맷을 사용합니다. 

이것은 iOS 장치의 ARM 프로세서 또는 Mac의 Intel 프로세서에서 실행되는 의미있는 chuncks로 그룹화된 바이트 스트림입니다.

 

 

< 추측 >

 

빌드 후, ~/Library/Developer/Xcode/DerivedData 에 들어가서

Mach-O 파일을 찾고  이 블로그 에서 열어준 방법으로 파일을 열어봤습니다..! 

어셈블러 단계에서 만들어진 파일이라고 추측합니다,, 

왜냐면 Intermediates~~ 로 시작하는 폴더 하위에 있는 파일이여서,, (어셈블러 전단계인 컴파일단계에서 Intermediate Representation만든다고 했으니까,,,?)

 

 

 

 

.o file을 한번 열어보겠습니다.

 

터미널에 이렇게 명령어를 쳐줄게요 (참고로 import UIKit 밖에 안한 뷰컨트롤러입니다)

hexdump 파일경로/ViewController.o

 

부분만 캡쳐했는데 기계어의 모습 맞습니다,,,

 

 

[4] 링커 Linker

 

링커는 iOS 또는 macOS 시스템에서 실행할 수 있는 단일 Mach-O 실행 파일 을 만들기 위해

다양한 objects 파일과 라이브러리를 병합하는 컴퓨터 프로그램입니다.

 

링커는 두 종류의 파일을 입력으로 가질 수 있습니다.

어셈블러 단계에서 나오는 object files랑

다양한 타입의 라이브러리들 입니다 (.dylib, .tdd, .a)

 

 

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

 

 

어셈블러와 링커 모두 Mach-O 파일을 출력으로 생성합니다.

하지만 그들 사이에 약간의 차이가 있습니다.

 

어셈블리 단계에서 나오는 object files은 아직 완료되지 않았습니다.

일부는 다른 object files나 라이브러리들을 참조하는 누락된 부분을 포함합니다. 

 

예를들어 printf 를 코드에 사용한 경우,

이 symbol을 libc library (printf function이 구현되어있는 라이브러리)와 연결시켜주는 것은 바로 링커입니다! 

컴파일러 단계에서 생성된 symbol table을 사용해서 여러 object files과 라이브러리들에 대한 참조를 확인합니다. 

 

 

< 추측 >

 

Build Settings > Linking > Mach-O Type에서

아래와 같은 타입들을 설정할 수 있잖아요..!

이것은 링커 단계의 아웃풋을 무슨 타입으로 할 건지 설정하는 것 같습니다.

 

 

만약에 앱 타겟에 Excutable이 아닌 다른 Mach-O Type을 선택하면 다 에러납니다. 

 

 

 

그러니까 

어셈블러 단계에서는 Relocatable Object File 타입의 Mach-O가 생성되고

링커 단계에서는 Build Settings에서 지정한 타입의 Mach-O가 생성되는 것 아닐까요..?!

 

[5] 로더 Loader

 

로더는 운영체제의 일부입니다. 프로그램을 메모리로 가져 와서 실행합니다.

로더는 프로그램을 실행하는 데 필요한 메모리 공간을 할당하고 레지스터를 초기 상태로 초기화합니다.

 

 

[ Reference ]

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

 

Understanding Xcode Build System

Every Swift program undergoes a number of transformations before it can be run on a real device. This process is usually handled by an Xcode Build System. In this article we'll take a look at each part of Xcode Build System: Swift compiler, linker, preproc

www.vadimbulavin.com

 

[ 더 보면 좋은 자료 ]

 

developer.apple.com/videos/play/wwdc2018/415/

 

Behind the Scenes of the Xcode Build Process - WWDC 2018 - Videos - Apple Developer

Ever wonder what happens when you build your project in Xcode? Learn how Xcode automates the steps required to build an application, and...

developer.apple.com

 

 

developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/building_files.html#//apple_ref/doc/uid/TP40001828-SW1

 

Building Mach-O Files

Building Mach-O Files To create programs, developers convert source code to object files. The object files are then packaged into executable code or static libraries. OS X includes tools to transform source code into a running application or a shared libra

developer.apple.com

 

 

 

reakwon.tistory.com/52 이 글처럼 단계별로 찍어보고 싶은데,,,  어떻게 해야할지 모르겠네요ㅠㅠ

 

 

반응형
댓글