- Published on
Flutter iOS 빌드 실패? CocoaPods 충돌 7가지
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
Flutter로 iOS 빌드를 하다 보면, 어느 날 갑자기 pod install 이 실패하거나 Xcode 아카이브 단계에서 링크 에러가 터지면서 멈추는 경우가 많습니다. 문제는 대부분 코드가 아니라 CocoaPods 의존성 해석 결과와 Xcode 프로젝트 설정이 엇갈리면서 발생합니다.
이 글은 "Flutter iOS 빌드 실패" 상황에서 실제로 가장 자주 마주치는 CocoaPods 충돌 7가지를 증상별로 분류하고, 확인 포인트와 해결 절차를 커맨드 중심으로 정리합니다. 단순히 pod repo update 같은 처방만 반복하지 않고, 왜 충돌이 생기는지까지 함께 설명합니다.
먼저 확인할 공통 전제 체크리스트
아래 4가지는 7가지 케이스를 보기 전에 공통으로 확인하면 진단 속도가 크게 올라갑니다.
- Flutter / Dart / Xcode / CocoaPods 버전 확인
flutter --version
xcodebuild -version
pod --version
ruby --version
- iOS 폴더 정리 후 재설치 기본 루틴
flutter clean
rm -rf ios/Pods ios/Podfile.lock ios/.symlinks
rm -rf ~/Library/Developer/Xcode/DerivedData
cd ios
pod deintegrate
pod install --repo-update
- Xcode에서 워크스페이스로 여는지 확인
- 반드시
Runner.xcworkspace를 열어야 합니다. Runner.xcodeproj로 열면 Pods 링크가 누락되어 빌드가 깨질 수 있습니다.
- 에러 로그에서 "진짜 원인" 줄 찾기
- CocoaPods 에러는 마지막 줄이 아니라 중간에 원인 제약이 나오는 경우가 많습니다.
- 예를 들어
Specs satisfying the ... dependency were found, but they required a higher minimum deployment target같은 문장이 핵심입니다.
1) iOS Deployment Target 불일치로 인한 Pod 해석 실패
대표 증상
pod install단계에서 실패- 로그에
required a higher minimum deployment target포함
예시 로그(요지)
- 어떤 Pod는 iOS 13 이상을 요구하는데 프로젝트는 iOS 12로 설정되어 있는 상황
원인
Flutter 프로젝트의 iOS 최소 타겟과, 플러그인이 끌고 오는 Pod의 최소 타겟이 다를 때 발생합니다. 특히 Firebase 계열, 광고 SDK, 최신 네트워크 라이브러리에서 흔합니다.
해결
ios/Podfile상단 플랫폼 버전을 올립니다.
platform :ios, '13.0'
- Xcode 프로젝트 설정에서도 동일하게 맞춥니다.
- Xcode
Runner타겟의iOS Deployment Target를13.0으로
- 다시 설치
cd ios
pod install --repo-update
2) Flutter 플러그인 간 Pod 버전 제약 충돌
대표 증상
CocoaPods could not find compatible versions for pod에러Firebase/CoreOnly (= x.y.z)와Firebase/CoreOnly (= a.b.c)처럼 서로 다른 버전을 요구
원인
서로 다른 Flutter 플러그인이 같은 iOS Pod을 다른 버전으로 고정하는 경우입니다. 예를 들면 A 플러그인은 GoogleUtilities 를 구버전으로, B 플러그인은 신버전으로 요구하는 식입니다.
해결 전략
Podfile.lock에서 충돌 Pod 이름과 버전 확인- Flutter 플러그인 버전을 정렬합니다.
pubspec.yaml에서 관련 플러그인을 최신 호환 조합으로 올리거나- 특정 플러그인을 내리면서 맞추는 방식
- 의존성 재해석
flutter pub upgrade
flutter pub get
cd ios
rm -rf Pods Podfile.lock
pod install --repo-update
팁: Firebase 계열은 firebase_core 와 각 서비스 플러그인의 버전 호환이 중요합니다. 플러그인 릴리즈 노트에서 iOS Pod 업데이트 내용을 꼭 확인하세요.
3) use_frameworks! 와 정적 라이브러리 충돌
대표 증상
- 링크 에러 또는 모듈 임포트 에러
ld: framework not found혹은Module 'xxx' not foundSwift pod xxx depends upon xxx관련 경고
원인
CocoaPods 는 크게 정적 라이브러리와 동적 프레임워크 방식이 섞이면 문제가 생길 수 있습니다. use_frameworks! 를 켜면 모든 Pod을 프레임워크로 빌드하려고 시도하는데, 일부 Pod 또는 Flutter 플러그인이 기대하는 방식과 충돌합니다.
해결
가능한 경우
use_frameworks!를 제거하고 기본(static)으로 유지합니다.꼭 필요하다면
use_frameworks! :linkage옵션을 사용해 충돌을 줄입니다.
use_frameworks! :linkage => :static
- 설치 재시도
cd ios
pod deintegrate
pod install
주의: 이 변경은 특정 SDK(예: Swift 기반 일부 SDK)에서만 필요합니다. 불필요하게 켜두면 오히려 충돌이 늘어납니다.
4) modular_headers 설정 불일치로 인한 헤더/모듈 충돌
대표 증상
Include of non-modular header inside framework module에러- 특정 Pod가 모듈로 임포트되지 않음
원인
일부 Pod은 모듈화된 헤더 구성이 필요합니다. Flutter 플러그인 조합에 따라 use_modular_headers! 또는 특정 Pod에만 :modular_headers => true 가 필요해집니다.
해결
- 전체 적용이 필요할 때
use_modular_headers!
- 특정 Pod만 모듈 헤더로 강제할 때
pod 'GoogleUtilities', :modular_headers => true
- 재설치
cd ios
rm -rf Pods Podfile.lock
pod install
팁: 전체 use_modular_headers! 는 다른 Pod에 부작용을 줄 수 있으니, 가능하면 특정 Pod에만 최소 적용하는 편이 안전합니다.
5) Apple Silicon 환경에서 아키텍처 충돌(시뮬레이터 빌드 실패)
대표 증상
- M1, M2, M3 맥에서 시뮬레이터 빌드 실패
building for iOS Simulator, but linking in object file built for iOS또는 아키텍처 관련 메시지
원인
일부 바이너리 Pod이 시뮬레이터용 아키텍처를 포함하지 않거나, arm64 시뮬레이터 환경에서 호환되지 않는 경우가 있습니다. 특히 오래된 SDK, 프리빌트 프레임워크에서 흔합니다.
해결
- 시뮬레이터에서
arm64제외 설정을 Pod 타겟에 적용
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
- 설치 후 재빌드
cd ios
pod install
flutter run
주의: 이는 시뮬레이터 한정 우회책입니다. 가능한 경우 해당 SDK의 최신 버전으로 교체하거나, XCFramework 형태로 제공되는 버전을 쓰는 것이 정석입니다.
6) Podfile.lock 과 Pods 캐시가 꼬여서 발생하는 유령 충돌
대표 증상
- 같은 설정인데 어떤 날은 되고 어떤 날은 안 됨
- 팀원 A는 되는데 팀원 B는 안 됨
pod install은 성공하지만 Xcode에서 링크 에러
원인
Podfile.lock 은 의존성 해석 결과를 고정합니다. Flutter 플러그인 버전을 바꿨는데 lock이 그대로거나, Pods 폴더와 lock의 상태가 불일치하면 "유령" 같은 충돌이 나옵니다. 또한 CocoaPods 캐시가 오래되어 잘못된 spec을 잡는 경우도 있습니다.
해결
- lock과 Pods를 함께 제거하고 재생성
cd ios
rm -rf Pods Podfile.lock
pod cache clean --all
pod install --repo-update
- CI에서도 동일 루틴을 적용
- iOS 빌드가 CI에서만 깨진다면, 캐시 전략이 문제일 수 있습니다.
- 이와 비슷한 맥락의 CI 권한/캐시 이슈는 아래 글의 접근 방식도 참고할 만합니다.
Docker BuildKit 캐시 무효화 원인·해결 8가지
7) Xcode 빌드 설정과 Pods 설정이 충돌(특히 SWIFT_VERSION, IPHONEOS_DEPLOYMENT_TARGET)
대표 증상
Swift compiler error로 보이지만 실제론 설정 충돌The sandbox is not in sync with the Podfile.lock또는 빌드 설정 경고가 연쇄적으로 발생
원인
Pod 타겟은 각자 빌드 설정을 갖고 있고, Xcode 프로젝트 설정과 엇갈리면 빌드가 깨집니다. 예를 들어
- 프로젝트는 Swift 5.0인데 특정 Pod은 Swift 5.7 전제
- 프로젝트 타겟은 iOS 12인데 Pod 타겟은 iOS 13
이런 불일치가 누적되면 "어디서부터" 깨졌는지 추적이 어려워집니다.
해결
post_install 훅에서 Pods 타겟 설정을 강제로 정렬합니다.
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
# 팀 정책에 맞춰 통일
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
config.build_settings['SWIFT_VERSION'] = '5.0'
end
end
end
적용 후
cd ios
pod install
주의: 무조건 강제로 덮어쓰는 방식은 일부 Pod의 요구사항을 무시할 수 있습니다. 에러가 난 Pod의 요구 버전을 먼저 확인하고, "통일"이 가능한 값으로 잡아야 합니다.
재현 로그를 빠르게 수집하는 방법
문제를 해결하려면 로그를 "정확히" 뽑아야 합니다. 아래 커맨드로 CocoaPods 및 Xcode 빌드 로그를 파일로 남기면, 팀 공유나 이슈 트래킹이 쉬워집니다.
CocoaPods 설치 로그
cd ios
pod install --repo-update --verbose | tee pod-install.log
Xcode 빌드 로그
xcodebuild -workspace Runner.xcworkspace -scheme Runner -configuration Debug build | tee xcodebuild.log
마무리: 충돌 해결의 우선순위
Flutter iOS 빌드 실패는 증상이 비슷해 보여도 원인이 다릅니다. 경험상 해결 우선순위는 아래가 효율적입니다.
- iOS Deployment Target 불일치부터 제거
- 플러그인 버전 충돌은
pubspec.yaml단계에서 정리 use_frameworks!와modular_headers는 최소 변경- Apple Silicon 아키텍처 이슈는 시뮬레이터 한정 우회 후 SDK 업데이트 검토
- lock, cache, DerivedData를 과감히 지우고 재생성
빌드/의존성 문제는 본질적으로 "상태" 문제인 경우가 많습니다. 그래서 CI 파이프라인에서도 같은 상태 재현이 중요합니다. iOS 빌드 자동화를 GitHub Actions로 운영 중이라면, 캐시와 권한, 재현성 관점에서 아래 글도 함께 읽어보면 도움이 됩니다.
GitHub Actions OIDC로 AWS 키 없이 배포하기
원하는 경우, 실제 에러 로그 일부(특히 pod install 실패 구간과 Xcode 링크 에러 구간)를 기준으로 "어느 7가지 중 어디에 해당하는지"를 매칭해서 더 구체적인 처방까지 정리해드릴 수 있습니다.