본문 바로가기

Flutter 앱 빌드 시 libarclite_iphoneos.a 및 아카이브 실패 문제

기술적인 이야기/기타 개발 2023. 4. 23.
반응형

회사 Flutter 앱 프로젝트를 iOS 용으로 빌드하던 도중 문제가 발생했다. 이 글 주제의 시작은 아래 오류 메시지로부터 출발한다.

Error (Xcode): File not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a

빌드하는데 필요한 libarclite_iphoneos.a 파일이 없다는 오류다. Xcode 14.3으로 올린 이후에 이런 문제를 겪었기 때문에 아마도 이 버전의 Xcode 문제라고 생각된다.

실제 에러가 발생한 터미널 스크린샷

위 메시지를 통해 두 가지 문제가 나왔고 이 두 가지 문제 해결의 과정을 정리해 보자. 명확한 해답이라고 하기엔 아직 지식이 부족하고 상당수는 외부에서 검색으로 얻은 지식이니 이런 부분은 참고했으면 좋겠다.

728x90

빌드 문제 해결

아마도 최신 버전에서 libarclite_iphoneos.a 파일이 빠진 채로 (혹은 의도적으로 뺀 채로) Xcode가 릴리즈 된 것 같고 그래서 Xcode 14.2 등 이전 버전으로 빌드하면 문제가 없다고 한다. 하지만 버전을 내릴 수 없다면 여기서 추출한 파일을 누군가 배포하고 있으니 (믿을 수 있는지는 잘 모르겠지만) 이를 이용할 수 있다.

터미널 셸에서 아래 코드를 입력하여 Xcode 툴체인의 lib 디렉터리로 이동한다.

cd /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib

여기에 arc 디렉터리를 만들어준다.

sudo mkdir arc

패스워드를 물어온다. 입력해 주자.

그런데 여기서 패스워드를 입력하면 허가되지 않았다는 오류가 뜰 수도 있다. 아무래도 현재 디렉터리를 만들려는 곳이 시스템 보호 구역이라 그런 것 같다. (참고로 이런 오류가 안 뜬다면 이리 설정된 상태이니 아래 설정 관련 부분은 생략해도 된다)

이를 해결하기 위해선 터미널에 전체 디스크 접근 권한을 부여해야 한다. 이 설정은 macOS의 '시스템 설정 앱 - 개인정보 보호 및 보안 - 전체 디스크 접근 권한 항목'에서 찾을 수 있다. 여기서 필요한 터미널 앱의 스위치를 활성화 후 터미널 앱을 재시작해주자.

iTerm에 전체 디스크 접근 권한을 부여한 상태

이제 다시 디렉터리 생성부터 시작하자. 위의 cd 커맨드로 디렉터리 이동은 이미 했다고 친다.

sudo mkdir arc

동일하게 패스워드를 입력하고 문제가 없다면 이제 해당 디렉터리로 이동하자.

cd arc

여기에 필요한 파일을 받아서 넣어주자. 아래 커맨드로 쉽게 넣을 수 있다.

sudo git clone https://github.com/kamyarelyasi/Libarclite-Files.git .

참고로 이번에도 sudo 커맨드를 사용하지만 앞서 패스워드를 입력한 지 얼마 되지 않았으면 이번엔 물어보지 않을 수도 있다.

이 Git 커맨드는 kamyarelyasi 사용자의 Libarclite-Files 저장소를 복제해 오는 커맨드다. 해당 저장소를 방문해 보면 알겠지만 일부 Cocoapods 패키지의 빌드 문제 시 요구하는 .a 파일을 배포하는 용도다. 이 파일은 정적 링크 용도로 빌드된 바이너리 오브젝트인데, 남의 바이너리 파일을 시스템에 박아야 한다는 게 찝찝하긴 한데 꼭 해야 한다면 어쩔 수가 없는 것 같다. 아니면 14.3.1 등의 버그픽스를 기다려 볼 수도 있을 것 같다.

이제 마지막으로 퍼미션을 풀어주자.

sudo chmod +x *

정적 라이브러리 파일에 실행 퍼미션을 주는 게 어떤 의미인지 모르겠는데 참고한 내역에는 하라니 하는 수밖에 없다.

이후 Xcode에서 빌드해 보니 잘 된다. Flutter를 통한 디버깅도 잘 되었다.

반응형

배포용 패키징(archive) 문제 해결

하지만 문제가 끝이 아니었다. 배포 빌드(archive) 시 AppAuth 패키지에서 제공하는 어떤 Phase Script에서 아래와 같이 rsync 오류가 난다. 뭔가 패키징 후속 처리에 문제가 생겼다는 말이다. 

PhaseScriptExecution [CP]\ Embed\ Pods\ Frameworks /Users/foobar/Library/Developer/Xcode/DerivedData/Runner-foooooobaaar/Build/Intermediates.noindex/ArchiveIntermediates/Runner/Interm
ediateBuildFilesPath/Runner.build/Release-iphoneos/Runner.build/Script-foobar.sh (in target 'Runner' from project 'Runner')
    cd /Users/foobar/Dev/realive-app/ios
    /bin/sh -c /Users/seorenn/Library/Developer/Xcode/DerivedData/Runner-foooooobaaar/Build/Intermediates.noindex/ArchiveIntermediates/Runner/IntermediateBuildFilesPath/Runner.build/Re
lease-iphoneos/Runner.build/Script-foobar.sh
mkdir -p /Users/seorenn/Library/Developer/Xcode/DerivedData/Runner-foooooobaaar/Build/Intermediates.noindex/ArchiveIntermediates/Runner/BuildProductsPath/Release-iphoneos/Runner.app/Fr
ameworks
Symlinked...
rsync --delete -av --filter P .*.?????? --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "../../.
./IntermediateBuildFilesPath/UninstalledProducts/iphoneos/AppAuth.framework" "/Users/foobar/Library/Developer/Xcode/DerivedData/Runner-foooooobaaar/Build/Intermediates.noindex/Archive
Intermediates/Runner/InstallationBuildProductsLocation/Applications/Runner.app/Frameworks"
building file list ... rsync: link_stat "/Users/foobar/Dev/realive-app/ios/../../../IntermediateBuildFilesPath/UninstalledProducts/iphoneos/AppAuth.framework" failed: No such file or directory (2)
done

sent 29 bytes  received 20 bytes  98.00 bytes/sec
total size is 0  speedup is 0.00
rsync error: some files could not be transferred (code 23) at /AppleInternal/Library/BuildRoots/foo-bar-qwer/Library/Caches/com.apple.xbs/Sources/rsync/rsync/main.c(996) [sende
r=2.6.9]
Command PhaseScriptExecution failed with a nonzero exit code

참고로 위 오류메시지에서 foobar 등으로 표기된 부분은 뭔가의 해싱 키 값 같은데 일단 개인정보일 수도 있어서 다 대체해 둔 것이다. 당연하게도 개인마다 해당 부분의 내용은 차이가 있을 수 있다.

어쨌든 에러의 핵심은 바로 "No such file or directory"다. 뭔가 잘못된 경로의 파일을 액세스 하려 하다 실패한 것으로 볼 수 있다.

이 문제 수정을 위해서는 해당 스크립트를 수정해야 한다. 참고로 이 과정은 명확한 해답이 아닌 개인적인 경험에 근거하고 있으니 더 좋은 방법이 있을 수 있다는 점을 먼저 알린다.

스크립트를 수정하기 전에 잠깐 먼저 pub get 과 릴리즈 빌드를 한번 실행시켜 주자.

flutter pub get && flutter build --release

이유는 나중에 나온다. 물론 빌드는 오류가 나는 상황 그대로인데 의도된 것이다. 상황에 따라 이 과정을 넘어가도 될 수도 있지만 개인적으론 안 하면 또 문제가 생겼기 때문에 꼭 하는 편이다. 빌드 옵션은 각자가 사용하는 옵션을 써야 할 것이다.

어쨌든 다시 원래 하려던 셸 스크립트 수정으로 돌아가자. 에러 상황에 따라 다르겠지만 내 경우 위 오류메시지가 나온 셸 스크립트를 추적해 보면 아래 파일이 실행된다는 것을 알 수 있었다.

ios/Pods/Target\ Support\ Files/Pods-Runner/Pods-Runner-frameworks.sh

이 부분도 사용자나 사용하는 패키지에 따라 다를 수도 있으니 추적하는 것은 직접 해야 한다. 모르겠다면 어쩔 수가 없겠지만 말이다.

이 파일을 좋아하는 편집기로 열어서 아래 항목을 찾아보자. 다 입력할 필요는 없고 'readlink'로 검색하면 몇 개 안 나와서 쉽게 찾을 수 있다.

source="$(readlink "${source}")"

이 코드를 -f 옵션을 추가하는 식으로 아래와 같이 수정해 주자.

source="$(readlink -f "${source}")"

이제 다시 빌드를 해야 하는데 주의할 점이 있다. 상황에 따라 배포 빌드 커맨드는 자동으로 pub get이 실행되면서 Pods의 내용도 업데이트가 되어버린다. 그래서 위의 수정 사항이 다시 원래도 돌아가버린다. 앞서 미리 pub get 및 빌드를 해주라고 한 이유가 바로 여기에 있다.

그러니 빌드할 때는 pub get이 실행되지 않도록 --no-pub 옵션을 추가해 주자.

flutter build ios --release --no-pub

이렇게 해서 빌드에 성공할 수 있었다. 업로드도 잘 되었고 테스트플라이트와 심사도 무사히 넘길 수 있었다.

사족

개인적으로 이 방식으로 빌드한 후 업로드까지는 문제가 없었다. 당장은 굉장히 불편한 상황이다.

물론 개발을 하면서 해당 셸 스크립트가 다시 원래대로 돌아가겠지만, 언젠가는 아예 문제가 수정되어서 업데이트될 것이라 기대하고 있다. 즉 시간이 지나면서 자연스럽게 해결될 휘발성이 높은 글이었다.

그래도 누군가에게 이 경험이 도움이 되면 좋을 것 같다.

[업데이트] 예상대로 문제가 재발해서 첫 주제만 다른 해결법을 찾아보았다.

 

또다시 나타난 libarclite_iphoneos.a 오류 (Flutter)

회사 업무용 Flutter 프로젝트를 오랜만에 빌드했더니 지난번에 글을 썼던 적이 있었던 libarclite_iphoneos.a 문제가 또다시 나타났다. 대충 축약해서 아래와 같은 동일한 오류다. Error (Xcode): File not foun

seorenn.tistory.com

728x90
반응형

댓글