-
느려터진 iOS 빌드 속도로 고통받는 당신에게, 카르타고를 권장합니다.iOS 2020. 4. 24. 00:23반응형
서론
카르타고를 왜 도입했는가.
iOS 라이브러리 의존성 관리 툴은 여러 가지가 있습니다. 그중 코코아팟이 제일 유명하고, 저도 코코아팟을 써 왔습니다. 코코아팟은 통소스를 다운로드하고, 컴파일할 때마다 라이브러리 소스를 같이 빌드합니다. 라이브러리가 많아질수록 클린 빌드의 속도가 느려집니다.
반면 카르타고는 라이브러리 소스를 미리 빌드합니다. 처음 라이브러리를 가져올 때에는 시간이 조금 걸리겠습니다만, 클린 빌드를 할 때 자체 코드들만 빌드하게 됩니다. 따라서 개발 중 빌드 시간이 줄어들게 됩니다.
갈수록 프로젝트에 스위프트 코드와 rxSwift 코드가 많아지니, 갈수록 컴파일 속도가 느려지게 되었습니다. 빌드 속도가 느려지면서 개발에는 차질이 생겼습니다. 한번 날 잡고 카르타고로 옮겨보자 했습니다.
적용한 결과는?
오십 개 정도의 라이브러리가 있는 코코아 프로젝트였습니다. 시뮬레이터와 실기기 모두 클린 빌드에 7~8분 정도 걸렸습니다. 카르타고로 전부 옮겨 보았습니다.
시뮬레이터에서는 120초, 실기기에서는 5분 정도로 단축되었습니다.
삽질에 걸린 시간은?
카르타고 검색, 적용, 검토까지 약 3주가 걸렸습니다. 신경쓸 게 정말로 많았습니다.
카르타고로 옮길 때 문제는 어떤 것이 있었는가
레포가 부족하긴 했지만, 처음에는 이렇게 옮기는 게 고생스러울 거라고는 상상조차 못했습니다...
까보니까 이곳저곳에 걸림돌이 많아 치우는 데 상당한 시간을 할애했습니다.
카르타고로 옮기는 것을 고민하시는 분들께, 이런 문제가 있을 것이라고 예고합니다.
1. 거의 모든 구버전 라이브러리의 버전을 올려야 하고, 앞으로도 극최신으로 라이브러리를 올려야 할 것이다
대다수의 구버전 라이브러리들은 카르타고를 사용할 때 문제를 겪습니다.
무조건 내부 xcode 기본 swift 버전으로 따라가는데, 빌드하는 버전과 라이브러리의 버전이 다르면 빌드의 오류가 뜨는 것 같습니다.
예를 들어, RxSwift를 저버전으로 카르타고로 업데이트하려고 하면 이런 오류가 뜹니다.
*** Checking out RxSwift at "5.0.1" *** Skipped installing RxSwift.framework binary due to the error: "Incompatible Swift version - framework was built with 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5) and the local version is 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15)."
Xcode 11.3.1 의 Swift 버전은 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15) 입니다. 그런데.. 프레임워크가 5.0.1 버전에서 빌드되었다고 오류를 뿜는 것입니다.
Xcode 구버전을 다운받으면 빌드할 수 있을 것으로 추측되나, 실제로 빌드해보지는 않았습니다.
Swift 마이너 버전조차도 이렇게 호환이 안 되는 것을 보아.. Xcode 가 출시될 때마다 라이브러리를 강제로 최신으로 올려야 되는 모양입니다. 물론, 메이저한 라이브러리들은 제깍제깍 지원을 해 주는 것 같습니다.
카르타고를 메이저로 쓰는 다른 회사에 물어본 결과... 이건 진짜 어떻게 할 방법이 없는 것답니다.
최신 Xcode 올라올 때마다, 구버전 라이브러리가 최신 Swift 로 빌드가 안 되면 라이브러리를 최신으로 올린답니다. 그래서 오픈소스는 유명한 것만 쓰고, 최대한 지양한다고 하네요. 필요하면 오픈 소스에 PR 도 날리고.. 여러모로 귀찮습니다.
결국, RxSwift, Alamofire, Moya 등등, 상당히 많은 양의 라이브러리의 버전을 올리게 되었습니다. 특히 Alamofire가 흉악합니다.
메이저 4에서 5 올릴때 네임스페이스같은 걸 싹다 바꿔 버렸습니다.
2. 복잡한 의존성을 가지는 것은 한번에 올려야 한다.
한번에 모든 라이브러리를 이전하는 것은 시간도 많이 걸리고, 테스트하기가 귀찮습니다.
일부 라이브러리 몇개 꺼내서 카르타고로 옮기고, 몇개 또 꺼내서 카르타고로 옮기고... 하는 것을 처음에 구상했습니다.
이때 골치아픈 것이 서로 의존성이 있는 라이브러리였습니다.
Moya, RxMoya는 Alamofire와 RxSwift 에 의존성이 있습니다. 처음에 Moya와 RxMoya를 옮기고, Alamofire와 RxSwift 는 남겨두려고 했습니다. 그 결과, 빌드 타임에 어떤 것을 링킹해야 할지 모른다고 에러가 났습니다.
결국 의존성으로 줄줄이 엮여 있는 라이브러리들은 원샷으로 올려야 합니다.
제 경우 아래 라이브러리는 별 도리 없이 한번에 이전해야 되는 것을 알았습니다.
- RxSwift
- RxCocoa
- Moya
- Alamofire
- RxMoya
- ReactorKit
- RxDataSources
- RxViewController
- RxOptional
- RxKeyboard
- RxGesture
- RxBlocking
- RxTest
- ReusableKit/RxSwift
3. 카르타고를 미지원하는 라이브러리들을 처리해야 한다.
라이브러리가 카르타고를 지원하기 위해서는, Xcode 가 업데이트 될 때마다 꾸준한 세부 조정이 필요합니다. 그 과정이 번거롭기 때문에, 상당한 양의 라이브러리들은 카르타고를 지원하지 않았습니다.
이런 경우, 직접 포크를 떠서 카르타고를 지원하도록 일일히 세부 작업을 해 주어야 했습니다. 레퍼런스가 별로 없어서 처음에 좀 헤매긴 했습니다. 익숙해지니까 반복 작업을 일일히 해 주는게 피곤했습니다.
카르타고를 지원하는 라이브러리를 제작하려면?
-
코코아 프레임워크를 생성합니다.
-
포크 뜬 프로젝트에 덮어씌웁니다.
-
shared scheme 에 체크합니다.
-
deployment target 을 프로젝트에 맞게 조정합니다.
-
기존 소스코드를 옮기고, copy if needed 에 체크 해제합니다.
-
objective-C 파일인 경우
- Build Settings 에서 헤더들을 모두 public 으로 옮깁니다.
- 메인 헤더에 퍼블릭 헤더들을 모두 임포트하도록 코드를 작성합니다.
-
의존성이 있는 경우
- Cartfile 을 만들어 의존성을 명시해준 뒤에, 프레임워크를 빌드하여 추가합니다.
-
이제 마지막입니다. Targets > Build Settings > Framwork Search Paths 에 갑니다. 그리고 $(PROJECT_DIR)/Carthage/Build/iOS 를 입력합니다.
4.코코아팟으로만 배포하고, 소스 코드를 공개하지 않는 라이브러리들을 따로 처리해 주어야 한다.
분석 SDK 툴의 경우, 전체 코드를 공개하지 않고 코코아팟에 바이너리만 올려놓는 경우가 많습니다. 이 경우, 포크를 떠서 카르타고를 지원하도록 만지작거릴 수 없습니다. 아이지에이웍스의 분석 sdk 같은 경우가 대표적인 예입니다.
바이너리를 적당한 곳에 올려서 처리하든지, 메뉴얼로 처리하든지, 뭐 기타 여러 가지 방법 중 하나를 선택해야 합니다. 저는 그런 경우는 메뉴얼 프레임워크를 다운받아서, 깃이그노어한 폴더에 추가하는 방법을 선택했습니다.
5. 기타 수많은 오류들이 각각 라이브러리마다 발생한다.
가뜩이나 iOS 레퍼런스는 부족한데, 카르타고에 관한 정보는 더욱 부족합니다. 근데 오만 라이브러리 다 옮길 때마다 이 에러 저 에러 다 발생했습니다. 간단히 소개해 보겠습니다.
1 ) Firebase 라이브러리 카르타고 이전 문제
파이어베이스의 경우, 바이너리로 빌드하는데 카르타고 업데이트를 두 번 하면 빌드가 죽어버리는 문제가 있습니다.
파이어베이스 깃허브 이슈에도 등록되어 있는데, 일반적인 'carthage update' 명령어 대신 아래 명령어를 치면 된다고 합니다.
carthage update --platform iOS --cache-builds \ || rm -rvf ~/Library/Caches/org.carthage.CarthageKit/binaries/Firebase** \ && carthage update --platform iOS --cache-builds
2) Texture 라이브러리 카르타고 이전 문제
현재 최신 텍스쳐 버전은 2.8입니다. 2.7 이하는 최신 엑스코드에서 카르타고 빌드가 안 되므로, 무조건 최신을 써야 합니다.
하지만 최신 텍스쳐 버전에서는 GCC 컴파일러 버전으로, 비디오와 지도 관련 모듈을 컴파일할지 말지를 결정하고 있습니다. 이건 컴파일타임에 라이브러리도 같이 말아버리는 코코아팟에서는 먹히지만, 카르타고에서는 허용되지 않는 방식입니다.
따라서 카르타고에서 ASVideoNode 등을 쓰려면, 라이브러리를 포크를 떠서 Base/ASAvailability.h의 아래 코드를 수정해야 합니다.
#ifndef AS_USE_VIDEO #define AS_USE_VIDEO 0 #endif
https://github.com/TextureGroup/Texture/issues/1471
작년 4월에 올라왔는데 고쳐줄 생각은 없어 보입니다.
결론
상당히 오랜 시간동안 카르타고로 이전을 완료했습니다. 공수가 깨나 많이 걸렸지만 굉장히 쾌적한 기분이 듭니다.
최근 들어 RxSwift 코드가 늘어나면서 빌드 속도가 말도 안 되게 늘어나서 개발에 답답한 점이 많았습니다. 코드 몇 줄 수정하고 빌드해보려면 5분 정도가 걸리고 말입니다.
하지만 옮기면서 정말 삽질도 많이 한 것도 있습니다만, 기기에 빌드할 때에는 속도 차이를 거의 체감하지 못해겠다는 게 아쉽습니다. 시뮬에서는 5분 정도 빌드가 단축된 것과 대조적이죠. 또 몇개 옮기고 몇개 옮기고 하면서 재 봤는데, 전부 옮기지 않으면 유의미한 성과가 안 나오는 현상도 있었습니다. 아예 코코아팟으로 가든지, 전부 카르타고로 옮겨 버리던지 하는 게 효율적입니다.
아무튼 라이브러리라도 컴파일을 안 하니, 시뮬레이터에서 빌드하는 경우 2분 정도밖에 걸리지 않습니다. 개발의 효율이 높아진 것은 분명합니다.
참고 레퍼런스
카르타고 의존성 이슈 관리하기
https://blog.dehol.kr/manage-dependency-issue-for-carthage/
- Moya 를 깔면 RxSwift, ReactiveSwift 가 주렁주렁 달려와서. Cartfile.resolved 를 억지로 수정해줘서 강제 빌드해줬다는 내용.
카르타고가 무엇인지 알아봅시다.
https://devmjun.github.io/archive/Carthage
- 정리 잘 된 튜토리얼.
[iOS Swift] 카르타고(Carthage) 란? 사용법은? 예제 따라하기까지!!
https://medium.com/@jang.wangsu/ios-swift-카르타고-carthage-란-사용법은-예제-따라하기까지-127e71fdd253
- 역시 튜토리얼.
킹피셔 카르타고 설치 가이드
https://github.com/onevcat/Kingfisher/wiki/Installation-Guide
반응형'iOS' 카테고리의 다른 글
Xcode 11 에서 애드훅으로 앱을 배포하는 방법, 드롭박스나 구글 클라우드 이용보다 확실한 배포 방법 (1) 2020.04.26 [잡설] 빌드 속도 단축에 대한 고민 (0) 2020.04.25 SWIFT 질문들 (0) 2020.03.14 iOS 13에서 리뉴얼된 위치 정보 변경 필독 사항 2 - 위치정보 한 번 허용 (0) 2020.03.07 iOS 13에서 리뉴얼된 위치 정보 변경 필독 사항 1 - 위치정보 지연된 항상 허용 (0) 2020.03.07