Unity로 iOS 빌드를 뽑아서 Xcode로 열었는데 Undefined symbols for architecture arm64 에러가 뜬 적, 다들 한 번쯤 겪어보셨을 겁니다. 보통은 .a(정적 라이브러리)나 .so 파일이 없어서 링커가 심볼을 못 찾아 생기는 문제인데, 원인이 한두 가지가 아니라 삽질하기 딱 좋은 에러이기도 합니다.
이번 글에서는 SVN(TortoiseSVN)을 쓰는 프로젝트에서 의외로 자주 발생하는 원인과 그 해결 방법을 정리했습니다.
⚡ TL;DR — 바로 이것부터 확인하세요
TortoiseSVN → Settings → General → Subversion → Global ignore pattern 여기에
*.a,*.so가 등록되어 있진 않은가요?
등록되어 있다면 아래 3단계로 해결합니다.
| 단계 | 할 일 | 명령 / 위치 |
|---|---|---|
| 1. 확인 | 실제로 무시된 파일이 있는지 확인 | svn status --no-ignore |
| 2. 설정 제거 | Global ignore pattern에서 확장자 삭제 | *.a, *.so 제거 |
| 3. 강제 add | 누락된 파일을 SVN에 재등록 | svn add Plugins/iOS --force --no-ignore --depth infinity |
이 3줄이 이번 글의 결론입니다. 왜 이런 일이 생기는지, 커맨드의 각 옵션이 무슨 의미인지 궁금하신 분들은 아래에서 이어서 보세요.
원인: 왜 TortoiseSVN 설정 때문에 파일이 사라질까?
Unity 프로젝트에서 네이티브 플러그인(.a, .so)은 Plugins/iOS, Plugins/Android 폴더에 바이너리 그대로 저장소에 커밋되어 있습니다. 그런데 TortoiseSVN의 Global Ignore Pattern에 이런 패턴이 등록되어 있으면:
*.so *.a *.tmp *.bak
이건 로컬 클라이언트 설정이라 저장소가 아니라 그 컴퓨터의 SVN 클라이언트 동작 자체를 바꿔버립니다. 매칭되는 파일은 svn status에서 “관리 대상 아님”으로 표시되고, svn add·svn commit 작업에서 아예 보이지 않는 파일처럼 취급됩니다.
문제는 팀원이 새 라이브러리 파일을 커밋할 때 본인도 모르게 빠뜨리게 된다는 점입니다. 커밋 창에 그 파일이 애초에 목록으로 뜨지 않으니까요. 그 상태로 다른 팀원이 업데이트를 받으면 저장소에 파일 자체가 없으니 로컬에도 받아지지 않고, 나중에 Unity가 iOS 빌드를 만들 때 그 라이브러리를 참조하는 심볼을 못 찾아 Xcode에서 Undefined symbols가 터집니다.
CocoaPods 미설치나 Build Settings의 Search Path 문제도 흔한 원인이지만, 그쪽은 이미 잘 알려져 있으니 이 글에서는 SVN 케이스에 집중합니다.
해결 방법 (자세히)
1️⃣ 무시된 파일이 있는지 먼저 확인
svn status --no-ignore
이 옵션을 주면 평소엔 안 보이던, ignore 패턴에 걸려있는 파일들이 앞에 I 표시와 함께 나타납니다. Plugins/iOS/xxx.a가 I로 뜬다면 그 파일은 SVN에 정상적으로 버전 관리되고 있지 않다는 뜻입니다.
2️⃣ Global Ignore Pattern에서 확장자 제거
TortoiseSVN → Settings → General → Subversion → Global ignore pattern
여기서 *.a, *.so를 지웁니다. 컴파일 산출물인 .obj, .tmp와 다르게, .a/.so는 Unity 플러그인 프로젝트에서는 버전 관리해야 하는 바이너리 소스입니다.
3️⃣ 이미 빠진 파일을 SVN 코드로 강제 add
설정만 고쳐서는 이미 어긋난 상태가 바로 해결되지 않습니다. 커맨드라인 SVN으로 명시적으로 추가해줘야 합니다.
파일 하나만 지정할 때 — 파일명을 명시하면 ignore 패턴은 무시됩니다.
svn add Plugins/iOS/libSomething.a --force
폴더 전체를 한 번에 처리할 때 — --force만으로는 global-ignores 설정을 여전히 존중하므로, 무시된 파일까지 잡아내려면 --no-ignore를 반드시 같이 줍니다.
svn add Plugins/iOS --force --no-ignore --depth infinity
| 옵션 | 역할 |
|---|---|
--force |
이미 버전 관리 중인 디렉토리 안의 새 파일까지 훑어서 add |
--no-ignore |
global-ignores / svn:ignore 패턴을 무시하고 add 대상에 포함 |
--depth infinity |
하위 폴더까지 재귀 처리 (파일만 필요하면 --depth files) |
add 후 A 표시가 제대로 붙었는지 확인하고 커밋합니다.
svn status
svn commit -m "Fix: Plugins/iOS 정적 라이브러리 누락분 재추가 (global ignore pattern 이슈)"
4️⃣ 재발 방지
- 팀 전체에 공유해서 각자 로컬 Global ignore pattern에
*.a/*.so가 없는지 점검하도록 안내하세요. 이 설정은 저장소가 아니라 각자 컴퓨터의 로컬 설정이라, 한 사람이 고쳐도 다른 팀원 PC엔 그대로 남아있습니다. - 가능하면 팀 전역 설정 대신 저장소 레벨의
svn:ignore/svn:global-ignores속성으로 관리하세요. 이 속성은 저장소에 커밋되므로 팀원 전체에게 동일하게 적용됩니다.
체크리스트
Unity iOS 빌드에서 Undefined symbols 에러를 만났다면:
- CocoaPods 관련 문제인지 (
pod install여부, Workspace로 열었는지) - Build Settings의 Search Paths 문제인지
- SVN 프로젝트라면, TortoiseSVN Global ignore pattern에
*.a/*.so가 등록되어 라이브러리 파일이 리포지토리에 안 올라가 있는 건 아닌지
3번은 “파일은 있는데 빌드에서 안 잡힌다”가 아니라 “애초에 SVN 저장소에 파일이 없다”는 다른 종류의 문제라 놓치기 쉽습니다. svn status --no-ignore 한 번이면 바로 확인되니, 비슷한 에러를 만나셨다면 꼭 체크해보세요.
