Xcode 프로젝트 내부 경로 관리

이 글은 갑자기 문득 A 제자가 질문한 것을 대답하고나서, 10년 전에 썼던 Xcode4 책에 Xcode 소스트리를 설명했던 내용이 생각나서 쓰기 시작했다. 물론 소스트리는 이제 사라졌다.

Xcode4가 나온 시점에 타임라인으로 넣었던 그림이다. 그리고 십년이 지나고 Xcode 12.x를 사용하는 지금 기준으로 분명히 더 좋아지고 개선된 부분도 있지만 크게 달라지지 않은 부분도 있다. 그 중에서 거의 변화가 없는 프로젝트 내에 경로 관리 부분이다.

어떤 언어로 개발하든지 프로젝트에 디렉토리와 파일이 많아지면 관리하기가 복잡하고 어려워진다. 일정 개수가 넘어가면 한 눈에 들어오지 않고, 여러 디렉토리로 나눠지면 어디에 있을지 예측하기 어려워지면서 찾아야 하기 때문이다.

Xcode 프로젝트라고 외는 아니다. 프로젝트 내에 타깃이 여러 개가 생기고, 타깃 내에 소스 파일과 리소스 파일이 많아지면서 한꺼번에 기억하기 어려운 상태가 되기 쉽다. 그래서 프로젝트 내 디렉토리를 익숙한 구조로 나누고 파일을 분산시키는 데 노력이 필요하다.

오늘 받았던 질문은 바로 이거였다.

프로젝트에 추가한 디렉토리와 파일들은 보통은 상대 경로를 사용한다. 같은 저장소를 사용한다고 해서 모든 파일이 절대 경로가 같아야 하는 것은 아니니까. 오히려 프로젝트에 파일을 추가할 때 절대 경로를 사용하는 경우는 더 문제가 된다.

화면 캡처를 하기 위해서 iOS 프로젝트를 바탕화면(Desktop)에 생성했다. Sample 프로젝트 경로는 /Users/godrm/Desktop/Sample 이고, Sample 프로젝트 내에 템플릿에서 만들어진 소스 코드가 들어있는 Sample 그룹 경로는 /Users/godrm/Desktop/Sample/Sample 이다.

프로젝트 파일의 위치는 Identity 인스펙터 Location 항목에서 확인할 수 있다. 기본값은 “Relative to Group” 그룹에 대한 상대 경로를 사용한다. Sample 프로젝트 아래 Sample 그룹 아래에 있는 ViewController를 선택하면 파일의 경로는 /Users/godrm/Desktop/Sample/Sample/ViewController.swift가 된다.

로컬에서 프로젝트에 secret.key 비밀 파일을 추가하고 해당 파일만 빼고 원격 저장소에 푸시해서 올렸다고 생각해보자. 그 프로젝트를 받은 다른 개발자에게는 프로젝트에는 secret.key가 있지만 파일이 해당 경로에 없으니까 빨간 색으로 보이고 빌드할 때 에러가 날 것이다.

이렇게 프로젝트 경로 내에 있는 파일을 제외하는 것보다는 별도 경로에 비공개 파일을 모아 놓고 싶다면 어떻게 해야할까?

절대 경로를 지정하면 의외로 간단하게 해결할 수 있다. 단, 경로가 모든 컴퓨터에서 다 동일한 절대 경로라면 말이다. 그런 경로가 어디가 좋을까? 바탕화면은 모두 있을테니 /Users/godrm/Desktop 나 /Users/godrm/Library가 절대 경로로 좋은 경로일까? 사용자마다 홈폴더가 달라지기 때문에 그렇지 않다.

그렇다고 /System 이나 /Library는 가능할 수 있지만, 권한 관리 측면에서도 좋은 것은 아니다. / 아래에 공통 디렉토리를 만들 수도 있겠지만, 파일과 디렉토리 자체를 절대 경로로 지정하는 것은 다른 개발 환경에서 깨지기 쉽다. 간혹 드래그 앤 드롭으로 프레임워크나 이미지 파일을 추가할 때 절대 경로로 추가하는 경우가 있다.

추천할 방법은 개발자 각자 로컬에서 사용하는 특정 경로를 프로젝트 공통 경로로 지정하는 것이다.

Location을 선택했을 때 맨아래 Relative to OurTeam 또는 Relative to MySource 같은 커스텀 경로를 지정하는 게 가장 좋다.

팀에서 사용하는 공통 상대 경로는 Xcode 설정 Preferences > Locations 탭에 Custom Paths 항목에서 추가할 수 있다. 원하는 이름과 표시 이름, 경로를 지정하면 된다. ~/Work/MySource 처럼 홈폴더 아래 상대 경로로 지정할 수도 있고, /Users/Shared/SourceTree 처럼 절대 경로로 지정할 수도 있다. 각자 개발자가 로컬에 특정 경로로 지정하고 사용하면 된다.

여기서 SourceTree라고 쓴 부분은 아틀라시안 git 클라이언트를 지칭하는 게 아니라 Xcode4 시절에 Custom Paths 메뉴가 바로 소스트리 SourceTree라는 이름이었다.

이제 secret.key 파일 location 경로를 Relative to OurTeam 으로 지정하고, OurTeam에 지정한 비공개 파일들을 모아놓으면 된다.

너무 짧게 끝나는 것 같으니까, Relative to Group 이외에 다른 항목들에 대해서도 정리했다.

  • Absolute Path : 말그대로 절대 경로가 그대로 지정된다. 특별한 경우가 아니라면 가급적 쓰지 말자.
  • Relative to Group : 파일이나 디렉토리가 포함되어 있는 그룹을 기준으로 상대 경로 (기본값)
  • Relative to Project : 환경 변수 PROJECT_DIR 값을 기준으로 상대 경로
  • Relative to Developer Directory : 환경 변수 DEVELOPER_DIR 값을 기준으로 상대 경로
  • Relative to Build Products : 환경 변수 BUILT_PRODUCTS_DIR 값을 기준으로 상대 경로
  • Relative to SDK : 환경 변수 PLATFORM_DEVELOPER_SDK_DIR 값을 기준으로 상대 경로

환경 변수들은 빌드 설정(Build Setting)에서 상수로 확인하거나 빌드 로그를 봐야 정확하게 알 수 있다. 프로젝트/타깃마다 실제 환경 변수가 궁금하다면 다음과 같이 export 명령을 실행하는 빌드 스크립트를 추가한다.

빌드 시점에 export 명령으로 확인할 수 있는 환경 변수들은 다음과 같다. 크게 PRODUCT 관련 항목과 PROJECT, TARGET 항목들을 구분할 수 있다.

그 외에는 빌드 환경, 개발자 도구, 플랫폼, 시스템 관련 환경 변수들이 있다. 이 값들은 빌드 설정(Build Setting)에서도 자주 사용하는 값들이니까 어떤 형태 값인지 확인해두기 바란다.

전체적인 환경 변수에 대한 설명은 이 곳 애플 개발자 문서를 참고하자.

https://help.apple.com/xcode/mac/current/#/itcaec37c2a6

최근 Xcode는 빌드 경로 Derived Data 기본 값은 환경 변수에 있는 ~/Library/Developer/Xcode/DerivedData 로 정해져있다. 이 값을 바꾸려면 File > Project Settings… 항목에서 바꿀 수 있다.

코드스쿼드 모바일 마스터

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store