[TIL] 빌드결과로 보는 정적,동적 프레임워크

rbw·2023년 8월 9일
0

TIL

목록 보기
87/98

https://sujinnaljin.medium.com/ios-%EB%B9%8C%EB%93%9C-%EA%B2%B0%EA%B3%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-static-framework-%EC%99%80-dynamic-framework-8568c5840e59
위 링크를 보고 정리해본 글 자세한 내용, 사진은 위 글 참 조 바라바라밤

Framework 생성 및 적용

간단한 덧셈 기능이 있는 프레임워크를 생성해서 프로젝트에 적용을 하심

프레임워크를 추가하는 방법은 기존 프로젝트에서 마우스 우클릭 -> Add Files to "프로젝트명" 그리고 프로젝트의 General -> Frameworks, Libraries, and Embedded Content 쪽에서 + 버튼을 통해 프레임워크를 추가해줌

이렇게 적용하면 import 해주어서 프레임워크 내부 로직을 사용할 수 있다.

Static Framework

기본적으로 Framework를 만들면 Mach-O Type이 다이나믹 라이브러리로 설정되어 있습니다. 지금은 Static을 테스트할거라 Static Library로 바꿔줍니다

Mach-O: Mach Object file format의 줄임말 Mach는 CMU에서 개발된 커널입니다.
얘는 의미가 있는 데이터 청크로 그룹화된 바이너리 스트림이라고 하네요. 바이트 순서, CPU 타입, 청크 크기등 메타정보가 들어갑니다.

프레임워크의 Build Settings에 들어가서 Mach-O Type을 변경하면 됩니다.

Static Library로 설정 후 빌드를 하면, 해당 프레임워크의 소스코드도 다 포함하여 메인 프로젝트가 실행이 됩니다. 이러한 이유로 최종적인 앱 크기가 커지는 것입니다.

실제로 소스코드가 다 포함을 하는지를 확인할 수 있는 방법은 nm 명령어를 사용하여 알 수 있습니다.

nm -debug-syms Project | grep "\.o" 명령어를 사용하면 해당 프로젝트의 오브젝트 파일에 대한 정보를 알 수 있습니다.

빌드가 완료가 되었다면 프레임워크 내부 코드는 프로젝트에 들어가있는 상태입니다. 따라서 기존에 폴더 구조 내부에 있는 프레임워크를 삭제해도 문제가 없습니다.

이를 삭제하는 방법은 Frameworks, Libraries, and Embedded Content에 적용했던 프레임워크의 옵션을 Embed & Sign 에서 Do Not Embed로 바꾸면 됩니다.

이를 적용하면 프레임워크가 사라집니다. 위의 옵션의 뜻은 해당 프레임워크의 모든 콘텐츠를 메인 앱과 함께 포장하지 말라 입니다. 따라서 최종 앱 패키지가 프레임워크 폴더 안에 있는 해당 프레임워크 코드를 포함하지 않습니다.

Dynamic Framework

이번에는 동적 라이브러리를 봐야하니, 추가한 프레임워크의 Mach-O Type을 Dynamic으로 적용해줍니다. 그런 다음 Embed 옵션을 Embed & Sign으로 적용합니다.

이제 빌드를 하고 폴더 구조를 살펴보면 다이나믹 라이브러리의 output이 별도의 executable binary로 생성된 것을 확인 할 수 있습니다.

이번에 메인 프로젝트에 nm -debug-syms Project | grep "\.o"를 실행해보면, 적용한 프레임워크의 목적파일이 없는걸 알 수 있습니다.

그러면 이 프로젝트는 어떻게 프레임워크의 로직을 수행할 수 있을까요 ?

바로, 동적 라이브러리에서 사용되는 심볼 및 런타임시 라이브러리의 경로를 기록하여 런타임시에 이를 찾아서 로직을 수행합니다. 따라서 Dynamic Framework를 적용하는 부분에서는 앱 크기가 막 커지지 않습니다.

이 링크가 되어있는 부분을 확인하려면 otool -L Project 명령어를 수행하면 알 수 있습니다.

@rpath/Myframework.framework/MyFramework라는 식으로 나오는데, 여기서 @rpath는 Runpath Search Path를 지칭하는 환경변수로, Xcode에서 기본적으로 @executable_path/Frameworks로 설정 되어 있습니다.

해당 경로를 프로젝트가 들고 있으므로, 프레임워크를 Embed할 때 이 경로를 통해 찾아가야 하므로 위에서 Embed 옵션을 Embed & Sign으로 설정을 해주었습니다.

만약 Do Not Embed로 설정을 한다면, 프로젝트에서는 프레임워크의 코드를 사용하지만, 오브젝트 파일이 없는 상태라 앱 내부에 없는 외부 심볼을 확인하기 위해 shared library를 확인하게 됩니다. 이 때 Do Not Embed 상태이므로 프레임워크가 폴더구조에 존재하지 않습니다. dyld:Library not loaded라는 동적 링커 쪽에서 에러가 발생하게 됩니다.

dyld는 동적 라이브러리를 로드하기 위한 것으로, 메인 실행 파일에서 시작합니다. Mach-O를 파싱하여 필요한 동적 라이브러리를 찾습니다. 동적 라이브러리를 사용하게 되면 앱 시작시 프로그램 파일 하나만 로드하는 것이 아니라, 모든 dylib들이 로드되고 함께 연결되어야 합니다. 그래서 앱의 시작 속도가 느려지는 것입니다.


정적, 동적 프레임워크에 대한 내용을 iOS 프로젝트를 예시로 살펴보아서 더 좋았던 글이였슴니다.

모듈화 관련으로 공부하고 적용하려면 이러한 내용을 좀 알아야한다고 얼핏 들었는데 나중에 공부할 때 이 내용이 도움이 되기를,,,

profile
hi there 👋

0개의 댓글