
컴파일된 여러 코드 조각들을 하나의 실행파일로 합치는 과정
컴파일: 컴파일러가 각 소스 코드 파일을 목적 파일(.o)로 변환
링킹: Linker가 흩어져 있는 목적 파일들과 필요한 라이브러리들을 모아 하나의 실행파일로 연결
컴파일 단계에서 호출된 함수를 찾아야 된다는 symbol을 표시 -> Linker가 목적 파일을 뒤져서 해당 함수의 실제 구현부를 찾아 symbol부분에 실제 구현부 주소와 연결
주소 재배치: 여러 파일을 하나로 합치면서 생기는 메모리 주소가 겹치는 부분을 메모리 위치를 재조정
.swiftmodule파일과.aordylib파일을 활용하여 연결
컴파일 타임에 코드 자체를 앱의 실행 파일로 복사하여 합치는 방식
컴파일 타임에 라이브러리에 작성된 코드들을 앱의 실행파일 안으로 복사되어 하나로 합침.
.a (Static Library) 또는 .framework (Static Framework) 파일 생성
.framework 파일은 내부 자체는 .a 이지만 리소스와 헤더가 포장된 폴더 구조
B 모듈 빌드: 컴파일하여 B 모듈의 ModuleB.swiftmodule 파일 + libModuleB.a 파일 생성
A 모듈 컴파일: 컴파일러가 .swift 파일 내부에 import Bmodule 확인 -> ModuleB.swiftmodule을 읽어 함수 정보 확인 -> 컴파일러가 함수 호출 위치에 링킹할 때 Bmodule 함수의 구현부 주소를 넣어야한다는 표시 작성
링킹: Amoudle.o 파일과 libModuleB.a 파일을 합침 -> Amodule.o에 표시된 부분에 libModuleB.a 파일 안에 있는 함수의 구현부 주소 연결
컴파일 타임에 라이브러리 구현부 코드들의 위치 정보만 기록하여 파일 생성
컴파일 타임에 라이브러리에 작성된 코드들의 위치 정보만 기록된 파일 생성
런타임에 dyld(dynamic linker)가 위치 정보를 확인하고 메모리로 로드하여 연결
.dylib (Dynamic Library) 또는 .framework(Dynamic Framework) 폴더 생성
.framework 폴더 내부는 .dylib파일과 리소스, 헤더가 포장된 구조
B 모듈 빌드: 컴파일하여 .framework 폴더 생성 (해당 파일 내부에 .swiftmodule 파일 존재)
A 모듈 컴파일: 컴파일러가 .swift 파일 내부에 import Bmodule 확인 -> ModuleB.swiftmodule을 읽어 함수 정보 확인 -> 컴파일러가 함수 호출 위치에 링킹할 때 Bmodule 함수의 구현부 주소를 넣어야한다는 표시 작성
링킹: 해당 함수가 B 모듈에 존재하는지 B모듈의 실행파일을 확인하고, Amoudle.o 파일 내부에 "이 함수가 실행되려면 저 파일에 찾아가"를 표시
Static: 코드 자체를 복사하는 과정 때문에 빌드 속도가 느려질 수 있음.
Dynamic: 구현부 코드의 주소만 포함하여 생성하기에 빌드 속도가 상대적으로 빠름.
Static: 이미 실행 파일 내부에서 모든 코드의 주소가 확정된 상태라 앱을 메모리에 올리기만 하면 되기에 빠름
Dynamic: 실행 순간에 dyld가 .framework 파일 내의 .dylib 파일을 확인하고 메모리에 올려 연결해야 하는 함수의 주소를 가리키도록 연결하는 과정이 발생하여 느림
Static: 여러 앱이 같은 라이브러리를 쓰더라도 각자 메모리에 올림.
Dynamic: 여러 앱 간 공유 가능 (UIKit과 같은 시스템 프레임워크 등이 그 예시)
Build Settings -> Mach-O Type에서 수정
https://www.swift.org/blog/abi-stability-and-more/
https://github.com/swiftlang/swift-evolution/blob/main/proposals/0271-package-manager-resources.md