[Xcode] Xcode12에서 시뮬레이터 빌드 오류 원인 및 해결방법

2020-10-07

이번 포스트에서는 Xcode12에서 시뮬레이터에 빌드시 오류가 발생하는 원인과 해결방법에 대해 알아 보겠습니다. 포스트가 제법 깁니다. 😅

간단히 알고 넘어가실 분은 TL;DR만 읽으셔도 됩니다.

TL;DR

빌드 오류 원인

  • Xcode12에서 ARM기반 맥(애플실리콘)을 지원함에 따라 아이폰 시뮬레이터에 ARM용 아키텍쳐 arm64가 추가돼 발생

해결 방법

Build Setting에

  1. EXCLUDED_ARCHS에 arm64를 추가
  2. VALID_ARCHS 제거

여기까지가 간단한 문제 원인과 해결방법입니다. 다음 내용부터는 보다 자세한 내용입니다.

❗️주의 : 내용 중 틀린 내용이 있을 수 있습니다. 발견하신 분은 바로잡아 주시면 감사드리겠습니다.

문제 원인 자세히 살펴보기

문제의 원인을 살펴보기전에 우선 Xcode에서 빌드와 관련해 알아야 할 내용이 두 가지 있습니다.

첫째, 아이폰은 기종에 따라 각기 다른 아키텍쳐의 CPU를 사용한다.

- arm64 : 아이폰 5S 및 이후 기종 (6, 6S, SE, 7…)
- arm7s : 아이폰 5, 5C
- arm7 : iOS7 지원 옛날 기기

아이폰 기기별 사용 아키텍쳐

둘째, 빌드시 바이너리가 생성되는데, 이 바이너리는 각 CPU 아키텍쳐에 맞게 생성해야 한다. (아키텍쳐별로 기계어 명령어 셋 등이 다름)

이제 본격적으로 설명을 시작하겠습니다.

앱을 하나 만들었는데, 이 앱을 아이폰 4S에서부터 최신기기인 iPhone 11까지 동작하도록 하려면 어떻게 빌드해야 할까요?

이 조건을 만족시키기 위해서는 arm64 바이너리 하나만 생성하면 안되고 arm64, arm7, arm7s 바이너리를 각각 생성해 원하는 모든 기기에서 동작할 수 있도록 해야합니다.

Xcode에서 이와 관련해 설정하는 부분은 Build Setting -> Valid Architectures 에 있었습니다.

Valid Architectures 설정(Xcode11)

이렇게 설정하면 빌드시 Valid Architectures로 지정한 모든 아키텍쳐 바이너리를 생성해 앱이 각 아키텍쳐를 사용하는 모든 기기에서 동작할수 있도록 할 수 있습니다.

여기서 질문! ✋

그렇다면 아이폰 시뮬레이터는 어떤 아키텍쳐를 사용할까요? 아이폰5 시뮬레이터면 arm7을 아이폰11시뮬레이터면 arm64를 사용할까요?

아닙니다!

아이폰 시뮬레이터는 맥에서 동작합니다. 그래서 아이폰 시뮬레이터는 맥 CPU의 아키텍쳐를 따릅니다. 요즘 맥은 core i5, i7 등의 인텔 CPU를 사용하고 있는데 이 CPU는 x86_64라는 아키텍쳐를 사용합니다. 그래서 시뮬레이터는 x86_64 아키텍쳐를 사용합니다.

다음 위치에 SKDSetting 파일에서 시뮬레이터 아키텍쳐 정보가 x86_64라는 것을 확인할 수 있습니다.

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/SDKSettings.json

Xcode 11 시뮬레이터의 아키텍쳐 : x86_64

Xcode에 아이폰11 기기를 연결하고 debug 설정으로 Run을 실행하면 어떤 일이 발생할까요?

앞에서 살펴본대로 Valid Architecture에 지정한 arm64, arm7, arm7s 용 빌드를 생성해 기기에 심습니다. 그런데 여기서 한가지 의문이 생깁니다.

아이폰11은 arm64 아키텍쳐를 사용하는데, 아이폰 11에다가 빌드하면 arm64 바이너리만 만들면 되지 굳이 arm7, arm7s 바이너리까지 만들 필요가 있을까?

맞습니다. 이럴때 사용하기 위한 옵션이 Build Active Architecture Only입니다.

Build Setting의 이 옵션을 활성화 시키면 Xcode에서 빌드시 Valid Architectures를 참조하지 않고, 현재 연결된 기기를 감지해 그 기기에 맞는 아키텍쳐용 빌드만 생성합니다. 다시말해 이 옵션을 활성화하고 아이폰11에 빌드를 하면 arm64용 바이너리만 빌드가 되는 것이죠.

시뮬레이터도 마찬가지 입니다. Run Destination을 시뮬레이터으로 선택해 Run을 수행하면 시뮬레이터 아키텍쳐를 감지해 해당하는 아키텍쳐 바이너리를 생성해 심습니다. 이 경우에는 x86_64 아키텍쳐 용 바이너리를 만듭니다.

이 옵션을 왜 debug 설정에서만 true로 설정해 사용하는지는 이제 이해가 되시죠?

여기까지가 Xcode12 이전에 빌드 수행시 기기 및 시뮬레이터에서 동작하던 방식입니다. 이제 Xcode12에서 달라진 동작에 대해 알아보겠습니다.

Xcode12 에서 동작하는 방식

먼저 Xcode12의 Release Note를 살펴보겠습니다.

Xcode12의 Release Note 내용의 일부

관련해서 얘기하고 있는 것은 크게 세 가지 입니다.

  1. Build Setting에 Valid Architectures(VALID_ARCHS)가 더 이상 포함되지 않음 (이 설정을 사용하는 것을 장려하지 않음)
  2. Valid Architectures 설정 대신 EXCLUDED_ARCHS 설정이 생김
  3. 기존 Valid Architectures 내용은 사용자 정의 섹션(User-Defined)에 노출됨

Valid Architectures(VALID_ARCHS) 설정이 더 이상 Architectures섹션에 있지않고 User-Defined섹션에 노출된 것을 확인하실 수 있습니다

정리하자면 기존에는 빌드시 원하는 아키텍쳐를 지정하는 방식을 사용했는데,

Xcode12에서는 반대로 빌드시 제외시킬 아키텍쳐를 지정하는 방식을 사용(필수x, 권장하는 부분)하는 쪽으로 바꼈습니다.

Xcode12에서 왜 이렇게 변경한걸까요?

그 이유는 바로 앞으로 출시될 ARM기반 맥북 때문입니다.

애플에서 머지않아 ARM기반 맥이 출시됩니다. 그동안 맥은 인텔 CPU기반이었습니다.(더 거슬러 올라가면 PowerPC) 하지만 곧 ARM용 맥도 출시가 돼서 앞으로는 인텔 CPU 기반 맥과 ARM기반 맥이 공존하는 상황이 됐습니다.

앞서 언급드린것처럼 아이폰 시뮬레이터는 맥의 아키텍쳐를 따릅니다. 현재 아이폰 시뮬레이터의 아키텍쳐는 x86_64입니다. ARM기반 맥은 arm64구조를 사용합니다.

Xcode12는 인텔 CPU 맥에서 ARM용 맥으로 넘어가는 과도기에 있는 앱으로, 두개 아키텍쳐를 모두 지원합니다. 다시말해 현재 사용 중인 x86_64 아이폰 시뮬레이터를 지원하고 앞으로 나올 arm64도 지원합니다.

바로 이 지점에서 시뮬레이터 호환성 이슈가 발생합니다.

전에는 시뮬레이터를 선택 후 빌드를 하면 x86_64용 빌드만 했는데, Xcode 12에서 시뮬레이터는 x86_64, arm64를 다 지원하기때문에 x86_64용과, arm64용으로 빌드를 수행합니다. 이 과정에서 현재 맥은 x86_64용 맥이기 때문에 arm64용 빌드 수행시 에러가 발생합니다.

다음 위치에 SKDSetting 파일에 Xcode12용 시뮬레이터의 아키텍쳐 정보가 x86_64, arm64라는 것을 확인할 수 있습니다.

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/SDKSettings.json

새로운 시뮬레이터의 아키텍쳐 : arm64, x86_64

빌드시 이 에러를 막기 위해서는 어떻게 해야할까요? 그렇습니다. 현재는 arm64용 맥북이 출시되지 않았기 때문에 시뮬레이터 빌드시 arm64용 빌드를 진행하지 않도록 해야합니다.

이 설정을 Xcode12 에서 새롭게 추가된 EXCLUDED_ARCHS에 설정할 수 있습니다.

EXCLUDED_ARCHS 변수를 설정하면 Xcode에서 Excluded Architectures 섹션에 노출됩니다.

Build Setting에 EXCLUDED_ARCHS 항목에

빌드를 시뮬레이터에 하는 경우에는 arm64 바이너리용 빌드는 하지 말아줘.

라고 지정을 하면 빌드시 arm64 빌드를 수행하지 않아 에러가 발생하지 않습니다.

이것이 이번 Xcode12에서 모든 아이폰 개발자를 힘들게 만든 원인 입니다.

해결하지 못한 내용

참고로 Xcode12 에서 시뮬레이터 빌드 오류를 수정하려면 기존에 VALID_ARCH 설정도 함께 지워야하는데, 이 부분은 애플에서 사용하지 않는 것이 좋다라고 언급한 내용 정도만 확인하고, 정확히 빌드오류 해결과 어떤 연관이 있는지는 확인하지 못하였습니다.

기존의 방식에 따르면 BUILD ACTIVE ARCHITECTURE ONLY를 세팅하면 위 설정은 참고하지 않는데… 왜 설정이 있다고 오류가 나는지는 잘 모르겠네요. 아시는분 알려주시면 감사드리겠습니다.

이상 Xcode12에서 시뮬레이터 빌드 오류 원인 및 해결방법에 대해 살펴봤습니다.

(👨🏻‍💻지식이 +10 늘었다. 이번 포스트는 지식+10 정도 되쥬? 인정이쥬? 🤣)

다음 포스트에서 또 만나요~ 🚀😄 (아마도 내년에~~)

[참 고]



[책] 토미의 Git with 소스트리

Git을 제대로 알고 싶으신 분들께 추천드립니다.