target은 빌드해야 할 Product가 무엇인지 명시하는 것과 빌드에 필요한 instruction들로 구성됩니다
즉, target은 하나의 Product를 정의하며 해당 product를 빌드하기 위해 빌드시스템으로 들어갈 input들(소스파일과 이 소스들을 처리하기 위한 instruction)을 구성합니다
instruction?
instruction은 빌드세팅과 빌드Phase로 구성됩니다. 당신은 이것들을 Xcode Project Editor에서 확인하고 수정할 수 있습니다
큰 그림에서 보면, Project
는 여러 개의 target을 가질 수 있으며, 각 target
은 하나의 product를 생산합니다
한 target이 빌드를 위해 다른 target의 output이 필요하다면 '의존'관계에 있다고 말할 수 있습니다
같은 workspace에 두면 Xcode가 '의존성'을 자동으로 탐지합니다
만약 두 target이 같은 workspace에 있다면, Xcode는 둘 사이의 의존성을 찾아내어 요구 순서대로 빌드하게 됩니다. 이런 관계를 '암시적 의존'이라고 표현합니다
예로, 라이브러리와 이 라이브러리를 의존하는 App을 같은 workspace에 두어 같이 빌드할지도 있습니다
Xcode는 이런 관계를 탐지하여 자동적으로 라이브러리부터 빌드합니다
명시적으로 '의존성'을 설정해줄 수도 있습니다
빌드 의존성을 빌드세팅에 명시적으로 설정할 수도 있습니다.
만약 같은 workspace에 있지 않은 라이브러리와 의존관계를 갖고 싶다면, 빌드세팅에 명시적으로 설정해주면 됩니다
또한, Xcode가 암시적으로 의존관계로 착각할만한 두 target 사이에 의존성이 없다고 명시할 수도 있습니다
기본적으로 target은 프로젝트의 빌드세팅을 물려받는데, 필요하다면 target level로 재정의해줄 수도 있습니다
한 번에 하나의 active target만 존재할 수 있습니다. Xcode scheme은 active target을 명시합니다
Xcode 프로젝트는 모든 파일/리소스/빌드정보들을 위한 저장소입니다
하나의 프로젝트는 'product들을 빌드하는데 사용되는 모든 요소들'을 포함하고 '각 요소들 간 관계'를 유지합니다
프로젝트는 여러 target을 가질 수 있습니다 (각 target에는 product을 어떻게 빌드할지 명시되어 있습니다)
프로젝트는 default 빌드세팅을 정의하고 이는 모든 target들에 기본적으로 적용됩니다. (필요하다면 target level에서 재정의 가능)
프로젝트는 아래 정보들을 포함합니다
Build Configuration은 여러 개 가질 수 있음. (예로, debug용 release용 두 개를 둔다던지)
이에 대해 자세한건 다음 챕터인 'Build Settings'에서 설명
각 target에 대한 아래의 것들을 명시합니다
product에 대한 참조
빌드하기 위한 소스파일들에 대한 참조
target level 빌드세팅
(빌드세팅에는 다른 target과의 의존성도 포함)
(target level 빌드세팅을 별도로 재정의하지 않으면 project level 빌드세팅을 사용)
프로젝트는 혼자 존재할 수도 있고 workspace에 포함될 수도 있습니다
Scheme을 사용해서 특정 시간에 active시킬 target/빌드세팅/테스트환경을 명시할 수 있습니다
빌드세팅은 product의 특정 빌드 프로세스를 어떻게 수행해야 할지에 대한 정보가 담긴 변수라고 보면 됩니다
예를 들어, 빌드세팅의 어떤 정보는 Xcode가 컴파일러에게 어떤 옵션을 전달할지 명시할 수 있습니다
빌드세팅은 project level도 가능하고 target level도 가능합니다
(default는 project level이고 별도로 재정의하면 target level도 가능)
Build configuration이란 것도 있는데 '특정 product'를 '특정 방식'으로 빌드하는데 필요한 Build Setting들의 '세트'를 말합니다.
예로, 하나의 product를 두고 debug와 release 방식으로 빌드할 때 별도의 Build Configuration을 설정하는 경우가 있습니다
Xcode에서 빌드세팅은 2개의 파트가 있습니다 (title / definition)
빌드세팅 title로 여러 빌드세팅들을 식별하고 다른 세팅에서 사용될 수 있습니다(?)
빌드세팅 definition은 상수 혹은 공식입니다. Xcode는 이것을 빌드타임에 빌드세팅의 값을 결정하기 위해 사용합니다(?)
또한, 빌드세팅은 display name을 가집니다. 이것은 Xcode User Interface에서 빌드세팅을 보여주기 위해 사용됩니다
기본적으로 새로운 프로젝트를 만들면 Xcode에 의해 default 빌드세팅이 제공됩니다.
이에 더해, 나의 프로젝트를 위해 사용자 정의 빌드세팅을 만들 수도 있습니다
또한, 조건부 빌드세팅도 만들 수 있습니다
조건부 빌드세팅의 값은 어떤 조건들이 충족되냐 마냐에 따라 결정됩니다
예로, 타겟 아키텍쳐에 따라 빌드에 사용할 SDK를 달리하도록 조건부 빌드세팅을 정의할 수 있습니다
워크스페이스는 프로젝트보다도 상위 개념으로 여러 개의 프로젝트들을 묶고(grouping) document들도 묶은 Xcode document입니다 (document가 단순히 '문서'를 뜻하는게 아닌 듯한데.. 대체 어떤 개념인가🥲)
또한, 포함시키고 싶은 다양한 파일들도 포함될 수 있습니다
워크스페이스는 각 Xcode 프로젝트의 모든 파일들을 구조화하는 것뿐만 아니라,
각 프로젝트와 target 간 암시적/명시적 관계를 추론/설정합니다
프로젝트는 자신에게 소속된 모든 파일의 참조를 갖고 있습니다 (+build configuration과 다른 프로젝트 정보들도)
하지만, 워크스페이스는 여러 프로젝트들을 포함하므로 자신에게 소속된 모든 프로젝트의 모든 파일의 참조를 갖습니다
참고
Xcode3 이전에는 프로젝트 '파일'은 항상 group과 file구조 계층의 'root'여야 했습니다
이로 인해, 비록 어떤 프로젝트가 다른 프로젝트들에 대한 참조를 가질 수는 있지만, Xcode3에서 프로젝트가 '서로' 상호작용하는 것은 복잡했습니다 (덕분에, 대부분의 workflow가 하나의 프로젝트에 한정되는 경향이 있었습니다)
Xcode4부터는 여러 개의 프로젝트(+기타 어떤 파일이든)를 hold하는 '워크스페이스'를 만드는 옵션이 생겼습니다
워크스페이스는 자신에게 소속된 각 Xcode 프로젝트의 모든 파일에 대한 접근성을 제공함에 더해, workflow에 대한 scope을 확장시켜 줍니다
예로, indexing이 워크스페이스 전체 범위에서 이루어지므로, code completion
이나 Jump to Definition
과 같은 코드내용인식 관련 기능들이 워크스페이스 전체 범위에서 매끄럽게 동작합니다
refactor
기능도 워크스페이스 전체 범위에서 동작하므로, framework 같은 것들을 분리된 프로젝트로 사용하고 있음에도 이를 사용하는 Application들과 한꺼번에 리팩터링할 수 있습니다
그리하여, 하나의 프로젝트가 빌드될 때 워크스페이스 내 다른 프로젝트의 product들을 사용할 수 있게 됩니다
워크스페이스 document에는 프로젝트나 파일들에 대한 '참조'는 들어있지만 'data'는 없습니다
그러므로, 하나의 프로젝트는 여러 워크스페이스에 소속될 수 있습니다
각 워크스페이스는 자신만의 build directory를 가지고 있고 기본적으로 해당 워크스페이스 내 Xcode 프로젝트들은 모두 이 폴더에 빌드됩니다(=workspace build directory
).
워크스페이스의 build directory는 default를 사용해도 되고 이를 따로 지정해도 됩니다.
하나의 워크스페이스 내 모든 파일들이 같은 빌드폴더에 있으므로, 모든 프로젝트에서 이 파일들이 보이게 됩니다.
보인다는 것은 소스로 사용할 수 있다는 의미입니다
만약 여러 프로젝트가 같은 라이브러리를 사용한다면, 각 프로젝트마다 이 라이브러리를 전부 복사할게 아니라 하나를 공유하면 됩니다
Xcode는 빌드폴더 내에서 암시적 의존성을 찾기위해 파일들을 전부 검사합니다
예로, 어떤 라이브러리 프로젝트가 있고 이 라이브러리를 사용하는 프로젝트가 있다면 Xcode는 자동으로 라이브러리부터 빌드합니다 (의존관계를 파악하여 빌드순서를 자동으로 조정함)
이는 '암시적 의존관계 추론'이므로 빌드 configuration에 명시해주지 않더라도 동작합니다
필요하다면, 빌드세팅을 명시적으로 주어 이런 암시적 의존관계를 재정의해버릴 수도 있습니다
(이런 명시적 의존관계를 정의하려면 대상이 될 프로젝트에 대한 '참조(reference)'를 만들어야 합니다)
워크스페이스 내 각 프로젝트는 고유한 ID를 갖습니다
하나의 워크스페이스 내에서 프로젝트끼리 영향을 주지 않게 하려면, 워크스페이스없이 프로젝트만 여는 방법이 있습니다. (혹은 워크스페이스를 하나 구해서 거기에 추가하던지)
하나의 프로젝트는 여러 워크스페이스에 소속될 수 있으므로, 이런 워크스페이스와 프로젝트들의 소속 조합을 활용해볼 수도 있습니다.
(A라는 프로젝트를 코드를 재생산할 필요없이 워크스페이스 소속을 다양화함으로써 B라는 프로젝트와 연결되게 빌드할 수도 있고 독립적이게 할 수도 있다는 뜻인듯?)
프로젝트를 워크스페이스에 두고 빌드하면 build directory는 워크스페이스를 따른다
만약 '프로젝트'가 build directory를 지정해놓은 상태더라도, 워크스페이스에 소속되면 해당 워크스페이스의 build directory를 따라 빌드됩니다
Scheme은 지금 당장하려는 빌드에 대한 설정으로,
어떤 target들이 대상인지 / 어떤 configuration을 사용할지 / test는 어떤 것을 실행할지를 정의합니다
원한다면 여러 개의 Scheme을 가질 수는 있으나, 한 번에 하나만 활성화(active)시킬 수 있습니다
그리고, Scheme이 하나의 '프로젝트'에 저장되어야 하는지 / 하나의 '워크스페이스'에 저장되어야 하는지 명시할 수 있습니다
(프로젝트에 저장하면 이 프로젝트를 포함하는 모든 워크스페이스에서 사용가능하고, 워크스페이스에 저장하면 해당 워크스페이스에서만 사용가능합니다)
활성화시킬 Scheme(active scheme)을 선택할 때, 대상이 되는 하드웨어 아키텍쳐도 선택할 수 있습니다