xcode-select와 DEVELOPER_DIR: 어느 쪽이 정석일까?
Expo 앱을 iOS 시뮬레이터에 띄우려고 도구부터 점검했는데, 결과가 앞뒤가 안 맞았습니다.
$ xcodebuild -version
xcodebuild: error: ...
$ swift --version
Apple Swift version 6.3.3 (swiftlang-6.3.3.1.3)Swift 컴파일러는 6.3.3 이 멀쩡히 답하는데 xcodebuild 는 없다고 합니다. 시뮬레이터 목록을 뽑으려 하니 더 이상했습니다.
$ xcrun simctl list devices
xcrun: error: unable to find utility "simctl", not a developer tool or in PATH/Applications/Xcode.app 은 자리에 그대로 있었습니다. 버전을 직접 읽어 보니 26.6, 빌드 17F113 이었습니다.
Xcode 를 안 보고 있던 활성 개발자 디렉터리
원인은 한 줄로 나왔습니다.
$ xcode-select -p
/Library/Developer/CommandLineToolsmacOS 에는 "지금 활성인 개발자 디렉터리" 라는 전역 설정이 하나 있고, xcrun 과 xcodebuild 는 전부 그 값을 보고 도구를 찾습니다. 그 값이 Command Line Tools 를 가리키고 있었습니다. CLT 에도 clang, swift, git 은 들어 있습니다. 그래서 컴파일러는 답했습니다. 반면 simctl, xcodebuild, 시뮬레이터 런타임은 Xcode.app 안에만 있습니다. 그래서 그쪽만 통째로 없었습니다.
Xcode 를 안 깐 것도 아니고 깨진 것도 아니었습니다. 가리키는 곳이 틀렸을 뿐입니다. 보통 Xcode 를 먼저 깔고 나중에 CLT 를 따로 설치하면 이 상태가 됩니다.
전역 설정을 피하려던 처음 판단
고치는 방법이 둘이라는 건 금방 알았습니다.
# 1. 전역 전환
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
# 2. 명령 단위 우회
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer npx expo run:ios저는 2번을 골랐습니다. sudo 가 붙는 게 마음에 걸렸고, 전역 설정을 바꾸면 다른 프로젝트에도 영향이 간다는 게 부담스러웠습니다. 부작용이 작은 쪽이 안전하다고 생각했습니다.
고르고 나서 뒤늦게 의문이 들었습니다. 부작용이 작다는 것과 옳다는 것은 다른 이야기입니다.
거꾸로 읽고 있던 "영향이 간다"
다시 보니 제 판단의 전제가 틀렸습니다.
전역 전환이 다른 프로젝트에 영향을 주는 건 맞습니다. 그런데 그 영향이 정상 방향입니다. 지금 상태에서는 이 머신의 어떤 프로젝트도 시뮬레이터를 못 씁니다. Flutter 를 깔아도, 다른 회사 앱을 클론해도 똑같이 simctl 을 못 찾습니다. 전환은 그걸 고치는 것이지 망가뜨리는 게 아닙니다.
제가 "부작용" 이라고 부른 것은 사실 "복구" 였습니다. 지키려던 상태가 애초에 정상이 아니었는데, 건드리지 않는 쪽을 보수적이라고 착각했습니다.
여기에 더해 우회는 비용이 계속 듭니다. DEVELOPER_DIR 은 환경변수라서 그 명령, 그 셸, 그 서브프로세스에만 붙습니다. 다음에 터미널을 새로 열고 npx expo run:ios 를 치면 그대로 실패합니다. Xcode 를 GUI 로 열어 쓰는 순간에도 안 따라갑니다. 그리고 실패했을 때 나오는 메시지는 방금 제가 본 그 "not a developer tool" 이라, 원인을 다시 처음부터 찾게 됩니다.
정석은 도구들이 전제하는 쪽
결정적인 근거는 생태계 쪽에 있었습니다. Expo, React Native, Flutter, Fastlane 문서가 하나같이 xcode-select -p 가 Xcode 를 가리킨다고 가정하고 쓰여 있습니다. 뭔가 안 될 때 그 도구들이 뱉는 안내문도 전부 xcode-select -s 를 실행하라고 합니다. 우회로 굴러가는 환경은 그 안내문과 계속 어긋납니다.
DEVELOPER_DIR 이 쓸모없다는 뜻은 아닙니다. 정당한 자리가 따로 있습니다.
xcode-select -s |
DEVELOPER_DIR |
|
|---|---|---|
| 적용 범위 | 머신 전체, 영구 | 그 명령 하나 |
| 권한 | sudo 필요 |
불필요 |
| 쓰는 자리 | 평소 개발 머신의 기본 상태 | Xcode 여러 버전 중 하나를 고정할 때, CI 처럼 전역 상태를 안 건드리는 게 원칙인 환경 |
우선순위는 DEVELOPER_DIR 이 높습니다. 그래서 CI 에서 Xcode 16 과 26 을 오가며 빌드할 때는 이쪽이 정확한 도구입니다. 제 경우는 Xcode 가 한 벌뿐이었으니 해당이 없었습니다. 예외 상황용 도구를 기본 상태에 쓰려 했던 셈입니다.
전환한 뒤
한 줄로 끝났습니다.
$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
$ xcodebuild -version
Xcode 26.6
Build version 17F113시뮬레이터는 11대가 잡혔고 iOS 26.5 런타임도 그때서야 보였습니다. CocoaPods 를 brew install cocoapods 로 1.17.0 을 깔고 npx expo prebuild --platform ios 를 돌리니 ios/ 생성과 Pod 설치까지 한 번에 지나갔습니다.
참고로 이 앱은 MapLibre 를 쓰는 터라 Expo Go 로는 아예 안 뜹니다. 네이티브 모듈이 들어간 앱은 dev client 를 직접 빌드해야 하고, 그래서 시뮬레이터가 없으면 화면을 볼 방법 자체가 없었습니다. xcode-select 한 줄이 막고 있던 게 그것이었습니다.
한 줄로 끝나는 원복
전역 설정이라 겁이 났던 것치고 원복은 간단합니다.
sudo xcode-select -s /Library/Developer/CommandLineToolsxcode-select 가 하는 일은 /var/db/xcode_select_link 심볼릭 링크를 바꾸는 것뿐입니다. 되돌릴 수 없는 변경을 피하려는 신중함은 좋지만, 그 변경이 실제로 되돌릴 수 있는지부터 확인했어야 했습니다. 저는 그걸 안 보고 우회부터 골랐습니다.
한 가지는 아직 확인 못 했습니다. Xcode 를 여러 버전 깔아 두고 프로젝트마다 다른 버전을 써야 하는 상황이라면 전역 전환만으로는 부족할 텐데, 그때 .envrc 같은 걸로 디렉터리 단위 DEVELOPER_DIR 을 거는 게 실제로 편한지는 안 써 봐서 모르겠습니다.
함께 읽기
- 새 맥북 개발 환경 세팅: git clone이 가져오지 않는 것들맥북을 새로 받고 하던 프로젝트를 이어서 하려 했습니다. 리포를 클론하고 npm install 을 돌린 다음 개발 서버를 띄웠는데, 브라우저에 이게 떴습니다.
- code 명령: PATH에 없을 때 등록하는 두 가지 방법터미널에서 VS Code로 뭔가를 열려고 code .을 쳤는데 command not found: code가 떴습니다. VS Code는 이미 깔려 있었습니다. /Applications/Visual Studio Code.app에 앱 자체는 멀쩡히 있었고, 문제는 그 앱을 실행하는 code 명령이 PATH 어디에도 없다는 것…
- macOS 클립보드 관리자, Swift·Tauri·Electron 중 무엇으로 만들까?클립보드 관리자를 만들겠다고 하면 첫 질문은 대개 "UI를 뭘로 짤까"입니다. React가 익숙하면 Electron이나 Tauri, 네이티브가 좋으면 SwiftUI를 떠올립니다. 그런데 이 앱의 화면은 검색창 하나와 목록 하나가 거의 전부입니다. 나머지는 운영체제와 주고받는 일입니다.
- Tauri 2로 클립보드 관리자를 만들면 네이티브 코드는 얼마나 남을까?지난 글에서 저는 클립보드 관리자를 Tauri로 만들면 가장 어려운 부분이 결국 네이티브 코드로 남는다고 썼습니다. 그 뒤 실제로 Tauri 2로 CopyFocus라는 클립보드 관리자를 만들었습니다. 결과부터 말하면 예상은 절반만 맞았습니다. 직접 짠 네이티브 코드는 생각보다 훨씬 적었고, 대신 예상하지 못한 곳에서 운…
- 데스크톱 앱 코드 서명 정리: macOS 공증부터 Windows SmartScreen까지직접 빌드한 .dmg를 다른 맥에 보내면 "확인되지 않은 개발자"라는 창이 뜨고 앱이 열리지 않습니다. 같은 앱의 Windows 설치 파일은 파란 "Windows의 PC 보호" 창에 막힙니다. 두 경고 모두 코드 서명이 없어서 생깁니다.