(Static/Dynamic) Library
안녕하세요 :) Zedd입니다.
~ 애플 문서를 보던 중 ~
💁 : 어떤곳은 Static Framework라고 하고..문서에서는 Static Library라고 하고... 뭔차이지..
이러한 궁금증은 아마 Xcode를 처음 열었을 때 드실 수도 있는데요.
Framework와 Static Library가 있죠@!!
오늘은 Library에 대해서 공부해보겠습니다.
# Library
구글에 검색하면 Library가 뭔지..이런 저런 정의가 많은데, 뭔가 다 아리송한 설명밖에 없더라구요 ㅠ 이해가 안됨..
찾고 찾다..다음 정의가 가장 와닿았는데요.
Xcode Target의 일부로 빌드되지 않은 코드 및 데이터 조각을 정의한 것
단순히 코드 및 데이터 조각을 정의했고, 이걸 내 앱 코드에서 가져다쓰고싶습니다.
라이브러리와 앱의 소스코드 파일을 병합(merge)하는 프로세스를 "Link"라고 합니다.
라이브러리는 앱에 Link되는 방식에 따라 두가지 카테고리로 나뉘게 됩니다.
🔹Static libraries
🔹Dynamic libraries
아직 위 두개가 뭔지는 모르지만, 두개를 구별하는 방법이 있습니다.
🔹Static libraries - .a
🔹Dynamic libraries - .dylib
.a 접미사(?)를 가지면 Static,
.dylib 접미사를 가지면 Dynamic입니다.
# Static libraries
프로젝트 만들 때 봤던거죠! 만들고 프로젝트에 추가하면 .a 로 끝나는 Static Library가 들어있는 것을 볼 수 있습니다.
자. 아까 Library는
Xcode target의 일부가 아닌 코드 및 데이터 조각을 정의하는 파일.
이라고 했습니다.
그중에서도 저는 Static library를 만들었습니다.
지금은 딱 이 단계인 것 같습니다.
Static library를 가져다 쓰려면
라이브러리와 앱의 소스코드 파일을 병합(merge)하는 프로세스를 "Link"라고 합니다.
Link작업이 필요합니다.
앱 소스코드 파일과 내 Static library.
두개를 merge하는 작업이죠? 화살표를 보니 확실히 merge되는 것 같네요. ㅎㅎ
이때 Static linker를 사용하게 됩니다.
Linker의 역할을 아주아주 간단하게 말하자면..
Linker는 input으로
- object파일
- Libraries (.dylib, .tbd, .a)
를 받고 단일 파일로 결합해주는 역할을 하는 친구입니다.
보통 link 과정은 컴파일 마지막에 일어나기 때문에
linker는 executable file을 생성한다고 보면 될 것 같습니다.
앱 소스 코드는 executable file안에 복사되게 됩니다.
그리고 static library 코드 역시 executable file에 복사됩니다.
static library가 executable file의 일부가 되기 때문에,
앱이 실행되면 앱 소스코드 + static library 코드를 포함하는 것들이 앱의 주소 공간에 로드됩니다.
이해가 가시나요? recap 해봅시다.
앱에 Static library를 추가하면,
1. 컴파일 시간에
2. Static linker가 library 코드 + 앱 코드를 merge하고
3. 단일 executable file을 만든다.
4. 앱이 실행되면 library 코드 + 앱 코드가 앱 주소공간에 로드된다.
여기서 추측할 수 있는게 있습니다.
1. 많은 static library를 앱에 link하면 큰 executable file이 생성됩니다.
왜냐? executable file안에 static library 코드가 복사되기 때문입니다.
2. 큰 executable file은 느린 시작 시간(launch time) + 큰 메모리 공간을 가져갑니다.
3. static libary가 업데이트 되면 클라이언트 앱은 개발자가 업데이트 된 library와 다시 Link하지 않는 이상 업데이트 된 기능을 사용할 수 없습니다.
딱 보니까 아 이건좀..이라는 생각이 들죠?!
static library가 많아질수록 큰 executable file이 만들어지고..
새 버전 나오면 또 다시 컴파일해서 Link 해줘야하고..
🤔 : 일단 내 library코드가 executable file에 포함안됐으면 좋겠어!
🧑💻 : Dynamic 어서오고
# Dynamic libraries
Dynamic library역시 library고, library는
Xcode target의 일부가 아닌 코드 및 데이터 조각을 정의하는 파일.
이었습니다.
똑같이 Link 프로세스를 거쳐야합니다.
그런데 결과물이 Static과 조금 다릅니다.
linker에 의해 만들어진 executable file에 library 코드가 모두 포함됐던 static과 달리,
Dynamic library에 대한 참조만 executable file에 포함됩니다.
이렇게요!
executable file과 Link는 됐지만, 복사가 안됐다는 점이 가장 중요합니다.
즉, executable file의 크기가 Static에 비해 작습니다!
🤔 : 일단 내 library코드가 executable file에 포함안됐으면 좋겠어! → ✅ 해결
아니 근데 Library 코드를 쓰긴 써야하는데..참조만 가지고 어케쓰나?
Dynamic library는 앱이 실행될 때 앱 주소 공간에 로드 됩니다.
1. 앱을 실행함
2. 앱 코드 + Dynamic library에 대한 참조가 앱 주소공간에 로드 된다.
3. 참조를 이용해 Dynamic library를 로드함
+ 이건 별로 안궁금해할 수도 있는데!
자..이런 Dynamic library를 로드하는 친구가 있는데요.
그것이 Dynamic loader라는 친구입니다. a.k.a dyld..
dyld: Library not loaded~ 이런 에러를 한번쯤은 보셨을 수도 있는데요.
dyld. 즉 Dynamic loader가
이 과정에서 Dynamic library를 가져오는데 실패했다는 겁니다.
그래서 항상 위 에러가 컴파일때 나는게 아니라.. 막 이제 앱이 막 시작하려고 하는데~~~~ 딱 났던 것이죠.
왜냐..? Dynamic library는 앱이 실행될 때 앱 주소 공간에 로드 되니간..
dyld가 Dynamic library를 가져오는 건 알겠어!
그럼 Dynamic library를 주소공간에 로드하는 시간도 한번 생각해봅시다.
Dynamic library가 많다 == dyld가 가져오는데 시간이 많이 걸린다.
이건 당연하겠죠?
dynamic library가 많을수록 pre-main time(main()이 실행되기 전까지의 시간)이 늘어나는데요.
이 pre-main time이 길수록 앱 launch time이 길어집니다.
Static library의 특징으로
큰 executable file은 느린 시작 시간(launch time) + 큰 메모리 공간을 가져갑니다.
를 이야기 했었는데,
dynamic library는 static에 비해서는 작은 executable file이 만들어지지만,
dynamic library를 로드하는 시간이 있고, 이는 pre-main 시간을 늘려 launch time이 오래걸리게 됩니다.
그에 반해 Static library는 이미 executable file안에 들어있기 때문에 dynamic library를 로드하는 시간이 줄어들게 되는것이죠.
그래서 WWDC 17 App Startup Time: Past, Present, and Future에서는
앱 시작 시간을 개선하고 싶다면, Dynamic library를 적게 embed해라~~라고 합니다.
한가지 궁금증은..
많은 Static library → 큰 executable file → 느린 시작시간
많은 dynamic library → 느린 시작시간
어느것이 더 느릴까...🤔
저는 Dynamic library가 많은게 더 느리지 않을까하는...
그리고 또 하나!
아까 Static library의 특징 중 하나가
Static libary가 업데이트 되면 클라이언트 앱은 개발자가 업데이트 된 library와 다시 Link하지 않는 이상 업데이트 된 기능을 사용할 수 없습니다.
라고 했어요.
Static libary의 코드가 executable file에 포함되기 때문에 컴파일을 다시 하여 Link를 해야하는 건 당연합니다.
하지만 Dynamic library는 그렇지 않기 때문에, 다시 컴파일하지 않고도 업데이트 된 기능을 사용할 수 있게 됩니다.
(모든 iOS, macOS 시스템 라이브러리는 Dynamic입니다.)
제가 Framework, Library를 정의도 모르는채 혼용해서 사용하는 것 같아서 이번기회에 좀 제대로 알자...!!!
하고 공부해봤는데요. 이 글을 쓰면서 궁금한 것들도 많았고..ㅎㅎ 틀린 내용도 있을 수 있을 것 같습니다.
틀린 내용이 있다면 댓글 남겨주세요~