- Published on
Flutter iOS 빌드 실패 - CocoaPods 오류 완전정복
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
Flutter로 iOS 빌드를 하다 보면 pod install 단계에서 막히거나, Xcode 링크 단계에서 Pods-Runner 관련 에러가 터지면서 CI까지 연쇄로 깨지는 경우가 많습니다. 문제는 에러 메시지가 길고(때로는 핵심이 뒤에 숨어 있고), 원인이 환경(Ruby, CocoaPods, Xcode), 의존성(플러그인), 설정(Podfile), 아키텍처(Apple Silicon) 등으로 분산되어 있다는 점입니다.
이 글은 Flutter iOS 빌드 실패를 CocoaPods 관점에서 원인별로 분해하고, 가장 재현율 높은 해결 루틴을 제공합니다. 목표는 한 번의 정리로 “다음에 같은 에러가 나도 어디부터 보면 되는지”가 머릿속에 맵으로 남는 것입니다.
1) 가장 먼저 확인할 것: 실패 지점과 로그 분리
Flutter iOS 빌드는 대개 아래 흐름입니다.
flutter pub get- iOS 폴더 생성/갱신(필요 시)
pod install또는pod update- Xcode 빌드(컴파일/링크/코드사인)
CocoaPods 문제는 주로 3번과 4번 사이에서 나타납니다. 따라서 에러가 pod install 단계인지, Xcode 빌드 단계인지 먼저 분리하세요.
flutter clean
flutter pub get
cd ios
pod --version
pod install --repo-update --verbose
pod install자체가 실패하면: Ruby/CocoaPods/Specs/네트워크/Podfile 문법/플러그인 podspec 문제 가능성이 큽니다.pod install은 성공했는데 Xcode 빌드가 실패하면: 링크 설정, iOS Deployment Target, 아키텍처, 모듈/헤더 설정, Swift/ObjC 브리징 이슈 가능성이 큽니다.
2) 환경 계층 문제: Ruby/CocoaPods/Xcode 버전 불일치
2-1. CocoaPods could not find compatible versions 류
대표적으로 다음 형태가 뜹니다.
CocoaPods could not find compatible versions for pod ...Specs satisfying the ... dependency were found, but they required a higher minimum deployment target
이 경우는 Pod가 요구하는 iOS 최소 버전이 현재 프로젝트의 Deployment Target보다 높다는 뜻인 경우가 많습니다.
해결
ios/Podfile에서 플랫폼 버전을 올립니다.
platform :ios, '13.0'
Xcode에서도 Runner 타깃의 Deployment Target을 동일하게 맞춥니다.
이후 재설치:
cd ios
rm -rf Pods Podfile.lock
pod install --repo-update
플러그인 업데이트로 iOS 최소 버전이 상향되는 일이 잦습니다. 특히 Firebase 계열, 광고 SDK 계열에서 흔합니다.
2-2. ffi / Ruby / xcode-select 관련 에러
Apple Silicon(M1/M2/M3)에서 Ruby 네이티브 확장(예: ffi)이 깨지거나, Xcode Command Line Tools 경로가 꼬여 pod 실행이 실패하는 케이스가 있습니다.
점검
xcode-select -p
xcodebuild -version
ruby -v
which pod
pod env
해결 가이드(권장 루틴)
- Xcode 경로가 이상하면:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
- CocoaPods는 시스템 Ruby에 얹기보다,
rbenv또는asdf로 Ruby를 고정하는 편이 재현성이 좋습니다.
예: rbenv 사용 시
rbenv install 3.2.2
rbenv global 3.2.2
gem install cocoapods
pod --version
CI에서도 동일 Ruby 버전을 맞추면 “로컬에서는 되는데 CI에서만 실패” 같은 사건이 크게 줄어듭니다.
3) Specs/Repo 문제: pod repo update로도 안 되는 경우
3-1. Unable to find a specification for ...
이 에러는 크게 두 갈래입니다.
- 로컬 Specs가 오래됨
- 해당 Pod가 사설 Specs/소스에 있거나, podspec 경로가 깨짐
해결
- 기본 업데이트:
cd ios
pod install --repo-update
- 그래도 안 되면 캐시/Specs를 강제로 정리합니다.
rm -rf ~/Library/Caches/CocoaPods
rm -rf ~/.cocoapods/repos
pod setup
pod repo update
pod install
네트워크가 느리거나 사내 프록시가 있는 환경에서는 pod setup 단계가 자주 실패합니다. 이때는 CI에서 CocoaPods repos를 캐시하거나, 사내 미러를 쓰는 전략이 필요합니다.
4) Podfile/빌드 설정 문제: Flutter iOS에서 자주 터지는 패턴
4-1. use_frameworks! / use_modular_headers! 충돌
일부 플러그인은 정적 라이브러리/동적 프레임워크 구성에 민감합니다. use_frameworks!를 켜면 빌드가 해결되는 경우도 있지만, 반대로 다른 Pod가 깨지기도 합니다.
안전한 접근
- 먼저 Flutter 기본 템플릿(최소 변경) 상태로 두고,
- 특정 SDK가 요구할 때만 제한적으로 적용합니다.
예: 동적 프레임워크가 필요한 경우
use_frameworks! :linkage => :dynamic
또는 모듈 헤더 이슈가 있다면:
use_modular_headers!
다만 이 설정은 “한 번 켜면 끝”이 아니라, 플러그인 조합이 바뀔 때마다 부작용이 달라질 수 있습니다. 변경 후에는 Podfile.lock까지 포함해 빌드 재현성을 확인하세요.
4-2. Runner 타깃/Pods 타깃의 빌드 설정 불일치
pod install은 성공했는데 Xcode 빌드에서 다음이 뜨는 경우가 있습니다.
ld: library not found for -lPods-Runnerframework not foundModule not found
이때는 xcworkspace가 아니라 xcodeproj를 열었거나, 빌드 설정이 꼬였을 가능성이 큽니다.
체크
- Xcode에서 반드시
Runner.xcworkspace를 열었는지 확인 - 스킴이
Runner인지 확인
리셋 루틴
flutter clean
rm -rf ios/Pods ios/Podfile.lock
rm -rf ios/.symlinks ios/Flutter/Flutter.framework ios/Flutter/Flutter.podspec
flutter pub get
cd ios
pod install
위 루틴은 Flutter iOS에서 “중간 산출물이 꼬여서 나는” 문제를 가장 빠르게 정리합니다.
5) Apple Silicon 아키텍처 이슈: 시뮬레이터에서만 실패
5-1. building for iOS Simulator, but linking in object file built for iOS
또는
Undefined symbols for architecture arm64Excluded architectures관련 경고
이 문제는 시뮬레이터 아키텍처(arm64/x86_64) 와 Pod가 제공하는 바이너리 아키텍처가 맞지 않을 때 발생합니다. 특히 오래된 바이너리 SDK에서 흔합니다.
해결 방향
- 가능하면 해당 SDK/플러그인을 최신으로 올려 arm64 simulator를 지원하게 만듭니다.
- 임시로 시뮬레이터에서 특정 아키텍처를 제외합니다.
Podfile의 post_install에서 처리하는 방식이 일반적입니다.
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
end
end
end
주의: 이 방법은 “빌드는 되게 하지만” 성능/미래 호환성 측면에서 임시 처방입니다. 장기적으로는 SDK 교체 또는 업데이트가 정답입니다.
6) 흔한 에러 메시지별 처방전(치트시트)
6-1. The sandbox is not in sync with the Podfile.lock
Pod 설치 상태와 Lock 파일이 불일치합니다.
cd ios
pod install
그래도 반복되면:
rm -rf Pods Podfile.lock
pod install
6-2. Pod installation complete! 이후 Xcode에서 No such module 또는 Module ... not found
Runner.xcworkspace를 열었는지 확인- DerivedData 정리
rm -rf ~/Library/Developer/Xcode/DerivedData
그리고 워크스페이스로 다시 빌드합니다.
6-3. clang: error: no such file or directory 와 Pods 헤더 경로
헤더 검색 경로가 꼬였을 때 나옵니다. 대개 flutter clean과 Pods 재설치로 해결되지만, 특정 플러그인이 헤더를 이상하게 제공하면 use_modular_headers!가 필요할 수 있습니다.
7) CI에서 자주 깨지는 포인트와 고정 전략
로컬에서는 되는데 CI에서만 실패한다면, CocoaPods는 거의 항상 “버전/캐시/네트워크” 문제입니다.
7-1. 버전 고정
- Ruby 버전 고정(예:
rbenv,asdf) - CocoaPods 버전 고정
gem install cocoapods -v 1.15.2
pod _1.15.2_ --version
7-2. Repo 업데이트 최소화
CI에서 매번 --repo-update는 느리고 실패 확률을 올립니다. 캐시가 있다면 Podfile.lock 기반으로 설치하고, 필요할 때만 업데이트하세요.
8) 문제 해결 접근법: “원인 격리”가 핵심
CocoaPods 오류는 한 번에 고치려 하면 늪에 빠집니다. 아래 순서로 원인을 격리하면 시간이 줄어듭니다.
pod install --verbose가 실패하는지부터 확인- 실패하면 Ruby/CocoaPods/Xcode 경로부터 정리
- 성공하면
Runner.xcworkspace로 Xcode 빌드 확인 - 시뮬레이터만 실패하면 아키텍처/바이너리 SDK 의심
- 플러그인 하나 추가 후 깨졌다면, 해당 플러그인의 iOS 최소 버전/Podfile 설정 요구사항 확인
이 방식은 운영 장애를 디버깅할 때 “증상-가설-검증”으로 접근하는 것과 동일합니다. 원인 격리 습관은 모바일 빌드뿐 아니라 인프라/백엔드에서도 그대로 통합니다. 예를 들어 장애를 단계적으로 좁혀가는 접근은 K8s CrashLoopBackOff 원인별 진단·해결 체크리스트 같은 글에서 다루는 방식과도 유사합니다.
또한 iOS Safari 환경에서 발생하는 성능/렌더링 문제를 다룰 때도 “레이어/컴포지팅/재현 조건”을 분리해야 빠르게 결론에 도달합니다. 관련해서는 Safari iOS scroll jank 해결 - 레이어 최적화도 함께 참고하면 좋습니다.
9) 실전: 가장 강력한 원복 스크립트(로컬)
아래는 iOS 빌드가 CocoaPods 주변에서 꼬였을 때, 가장 먼저 돌려볼 만한 원복 루틴입니다.
# 프로젝트 루트에서
flutter clean
flutter pub get
# iOS 의존성 초기화
rm -rf ios/Pods ios/Podfile.lock ios/.symlinks
rm -rf ios/Flutter/Flutter.framework ios/Flutter/Flutter.podspec
# Xcode 캐시(필요 시)
rm -rf ~/Library/Developer/Xcode/DerivedData
# CocoaPods 재설치
cd ios
pod install --repo-update
# 빌드
cd ..
flutter build ios --debug
- 위 루틴으로도
pod install이 실패한다면: 환경 계층(Ruby/CocoaPods/Specs/네트워크)을 먼저 고치고, pod install이 성공하는데도 빌드가 실패한다면: Xcode 빌드 설정/아키텍처/플러그인 자체 이슈로 좁히면 됩니다.
10) 마무리: “CocoaPods 오류”는 유형화하면 무섭지 않다
Flutter iOS 빌드 실패는 겉보기엔 복잡하지만, 실제로는 다음 네 축으로 대부분 정리됩니다.
- 환경: Ruby/CocoaPods/Xcode 경로와 버전
- 의존성: Specs 업데이트, Podfile.lock, 플러그인 요구사항
- 설정: Podfile 옵션, Deployment Target, 워크스페이스 사용
- 아키텍처: arm64 simulator, 바이너리 SDK 호환성
다음에 에러가 나면 에러 메시지를 전부 읽기 전에, 먼저 “지금은 pod install 단계인가, Xcode 링크 단계인가”부터 분리해 보세요. 그 한 번의 분기가 해결 시간을 절반으로 줄여줍니다.