광고


[VS2017] Unity(Jumbo) Files in VS 2017 15.8 (Experimental) VisualStudio


0. 서문


원문 URL을 보고 적용해 본 뒤, 간략하게 나름의 정리와 소고에 대해 작성한다.
"실험단계"라 그런지, 아쉬운 부분도 분명 존재하지만 이제라도 "Unity 빌드"를 정식으로 지원하려 하는 것은 분명 고무적이다.


1. Unity 빌드 옵션 활성화

실험단계여서 그럴까... VS2017 15.9.5에서도 "Unity 빌드"에 대한 설정은 기본적으로 비활성화되어 있다.
이를 활성화시키기 위해서는 1) 별도의 props 파일을 추가 또는 2) 기존 프로젝트 파일 수정으로, 다음의 PropertyGroup 설정을 추가해 주어야 한다.

  1.   <PropertyGroup>
  2.     <EnableUnitySupport>true</EnableUnitySupport>
  3.   </PropertyGroup>

저장 후 해당 프로젝트 속성을 열어보면, 아래 그림과 같이 C/C++ 속성에서 "Unity 빌드" 항목을 확인할 수 있다.



2. 개별 항목

위 설정 이미지를 보면 총 10개의 설정이 있는 것을 확인할 수 있다.

1) Unity 파일에 포함

* 프로젝트 속성에서 설정시 전체 파일에 적용되지만, 개별 파일에 대해서도 별도로 설정할 수 있다.

예를 들어, 프로젝트에 A~Z까지의 cpp 파일이 있을 경우 프로젝트 속성에서 "예"로 설정하면 기본적으로 모든 파일에 대해 "예"가 적용된다. 이후 개별 파일에 대해 "아니오" 지정시 해당 파일에만 override되어 적용된다.
(반대의 경우도 마찬가지다. 프로젝트 속성에서 "아니오"로 하고, 필요 파일들에 대해서만 "예"로 설정할 수 있다)

속성 이름 그대로 "예"로 설정해야 해당 cpp 파일이 unity_*.cpp 파일에 #include, 즉 포함된다.
프로젝트가 크면 클수록, 그리고 개별 파일들에 대한 설정이 늘어날수록 속성 XML 파일의 크기가 비대해지고, 이는 프로젝트 로드 속도에 영향을 줄 것이다.

"사용자 지정 unity 파일"이 "아니오"로 설정되어 있다면, 빌드 시스템은 "Unity 파일 디렉토리"에 자동으로 unity_*.cpp 파일들을 생한다. unity_xxx.cpp 파일들에 결합/포함되는 cpp들은 여러 설정들에 영향을 받지만, 우선 개별 파일의 컴파일 옵션이 다를 경우 다른 unity 파일에 포함되게 되는 점을 유념해야 한다.

2) Unity 파일의 순서 번호

* 프로젝트 속성에서 설정시 전체 파일에 적용되지만, 개별 파일에 대해서도 별도로 설정할 수 있다.

기본값이 100인데, 프로젝트 속성에서 100을 설정하면, 모든 파일에 100 기본값이 설정되어 순서번호가 모두 같게 되므로, 순서번호에 의해 포함 순서가 달라지진 않게 된다.
하지만, C.cpp 파일의 개별 순서 번호를 105 정도로 설정하게 되면, C.cpp 파일은 포함되는 unity_xxx.cpp에서 가장 뒤늦게 #include 될 것이다. (나머지 애들이 모두 100이므로...)

3) 동일한 폴더의 파일만 결합

프로젝트가 거대해지면, 유사 성격의 파일들끼리 동일 하위 폴더에 위치하게 되는 경우가 흔하다.
이 옵션은 이름 그대로 "가능한 한" 동일 폴더의 파일들끼리 하나의 unity_xxx.cpp에 포함시키도록 설정한다.

"가능한 한"이라고 표현한 것은 다음의 2가지 경우에 의해 이 옵션을 켜더라도 모두 하나의 파일에 포함되지 않을 수 있기 때문이다.
  • "Unity 파일에 포함" 챕터에서 얘기했듯이 cpp 파일간 컴파일 옵션이 다를 경우
  • 폴더 내 소스 파일의 개수가 "Unity 파일의 최소 소스 수"보다 적은 경우엔, 여러 개의 unity_xxx.cpp에 나뉘어 포함된다.

4) Unity 파일의 최소 소스 수

하나의 unity_xxx.cpp에 포함될 소스 파일의 최소 개수를 설정한다.
이 값이 4로 설정된 상태에서 A 폴더와 B 폴더의 파일 개수가 3개이고 "동일한 폴더의 파일만 결합"이 켜져 있는 경우엔 A/B 폴더의 소스 파일들이 하나의 unity_xxx.cpp 파일에 포함되게 된다.

프로젝트가 커져갈수록, 서브 디렉토리 내 파일들의 개수를 잘 고려해서 이 값을 설정하는 것이 좋다.
이 값이 작게 설정될수록 unity_xxx.cpp 파일의 개수가 많아질 것이고 이는 Unity 빌드의 잇점을 충분히 누리지 못하는 결과를 낳을 수 있기 때문이다.

5) 포함 전에 추가할 코드 조각

unity_xxx.cpp 파일 작성시 매 cpp 파일을 #include 하기 앞서 추가(삽입)되는 코드 조각을 의미한다.
예를 들어, 다음의 코드 조각이 있을 수 있다.

  1. #pragma message ("Unity compiling: $$file_name$$")
  2. #define UNITY_ID $$unity_id$$_$$file_number$$

이 코드 조각의 결과로 생성되는 unity_xxx.cpp의 내용은 다음과 같다.

  1. // { 포함 전에 추가된 코드 조각
  2. #pragma message ("Unity compiling: A.cpp")
  3. #define UNITY_ID 1GWLSU09BEGGZ58G_1
  4. // }
  5.  
  6. // { 포함된 cpp 파일
  7. #include "C:\Test\A.cpp"
  8. // }

코드 조각에 사용할 수 있는 매크로는 다음과 같은 것들이 있다고 한다.
  • $$unity_id$$ : 해당 unity_xxx.cpp의 xxx에 해당하는 부분, file hash string이다.
  • $$file_number$$ : 해당 unity 파일에서의 상대 순서
  • $$file_name$$ : 포함되는 소스 파일명
  • $$file_path$$ : 포함되는 소스의 full path

6) 포함 전에 추가할 파일 코드 조각

"포함 전에 추가할 코드 조각"은 직접 속성창에 내용을 입력하는 속성인 반면, 이 속성은 코드 조각들을 특정 cpp에 작성하고 해당 cpp를 지정하는 속성이다.

다음과 같이 UnityPrefix.cpp를 작성하고, 프로젝트 폴더에 위치시킨다면

  1. // UnityPrefix.cpp의 내용
  2.  
  3. #pragma message ("Unity compiling: $$file_name$$")
  4. #define UNITY_ID $$unity_id$$_$$file_number$$

이 속성에 "UnityPrefix.cpp"파일의 위치를 입력해 주면 "포함 전에 추가할 코드 조각"에서 코드를 직접 입력하는 것과 동일한 결과를 얻는다.

즉, 5) 6) 속성은 둘 중 하나만 설정하면 되는 것이다.

7) 포함 후에 추가할 코드 조각 / 8) 포함 후에 추가할 파일 코드 조각

5) 6) 속성에 "포함 전" 추가하는 코드/파일 코드 조각이었다면, 7) 8)은 포함 후에 추가되는 것을 의미한다.

예를 들어, 포함 후에 추가할 코드 조각에 "#undef UNITY_ID"를 지정했다면, 결과는 다음과 같다.

  1. // { 포함 전에 추가된 코드 조각
  2. #pragma message ("Unity compiling: A.cpp")
  3. #define UNITY_ID 1GWLSU09BEGGZ58G_1
  4. // }
  5.  
  6. // { 포함된 cpp 파일
  7. #include "C:\Test\A.cpp"
  8. // }
  9.  
  10. // { 포함 후에 추가된 코드 조각
  11. #undef UNITY_ID
  12. // }

9) Unity 파일 디렉토리

unity_xxx.cpp 파일들이 생성될 디렉토리를 설정한다.

기본값은 $(IntDir)로 되어 있다. 즉, 기본 생성 디렉토리는 Intermediate directory.
기본 지정된 위치가 임시 디렉토리인 것에 대해, 뒤에 작성된 아쉬운 점들을 읽다보면 조금은 이해가 갈 것이다.

10) 사용자 지정 unity 파일

이 문서는 VisualStudio가 Unity 빌드를 자동화시켜 주는 것에 방점을 두고 작성된 글이라, 이 부분에 대해선 딱히 작성치 않는다.
자세한 내용은 서문의 원문 URL 글을 참고하기 바란다.


3. 그 외 영향을 주는 부분

"Unity 빌드" 속성 페이지의 속성들과 별개로 Unity 빌드 파일들 생성에 다음의 것들이 영향을 준다.

1) 다중 프로세서 컴파일 (/MP)

이 설정이 "예"로 설정된 경우, Unity 빌드는 cl.exe에서 사용되는 프로세서의 개수 즉, 머신의 논리 코어수만큼 unity_xxx.cpp 파일을 만들어 내려 한다.
/MP가 켜져 있을 경우 cl.exe는 논리 코어수만큼 병렬 컴파일을 수행하기에, 그보다 파일 수를 적게 만들 이유가 없는 것이다.

물론 프로젝트의 규모에 따라, 논리 코어수보다 파일이 적게 생성될 수도 있고, 많게 생성될 수도 있다.
"Unity 파일의 최소 소스 수" 챕터에서도 작성했지만, unity_xxx.cpp 파일이 논리 코어수보다 너무 많게 생성될 경우 Unity 빌드의 효율이 떨어질 수 있으므로 적절한 옵션질을 해주어야 한다.

2) 미리 컴파일된 헤더

미리 컴파일된 헤더 파일이 프로젝트 속성에 명시되어 있을 경우, 생성되는 모든 unity_xxx.cpp 파일들은 먼저 PCH 파일을 포함하여 시작된다.

예를 들어, 프로젝트의 PCH이 TestPCH.h라고 명시되어 있을 경우 생성되는 unity_xxx.cpp는 다음과 같이 시작하는 것이다.

  1. // { 명시된 PCH 파일이 먼저 포함되어 시작
  2. #include "TestPCH.h"
  3. // }
  4.  
  5. // { 포함 전에 추가된 코드 조각
  6. #pragma message ("Unity compiling: A.cpp")
  7. #define UNITY_ID 1GWLSU09BEGGZ58G_1
  8. // }
  9.  
  10. // { 포함된 cpp 파일
  11. #include "C:\Test\A.cpp"
  12. // }
  13.  
  14. // { 포함 후에 추가된 코드 조각
  15. #undef UNITY_ID
  16. // }


4. 아쉬운 점

"실험단계" 치고는 생성되는 Unity 빌드 결과물이 나쁘지 않다. (물론 프로젝트 규모에 맞는 옵션 설정을 잘 해줘야 함)
하지만, 역시나 "실험단계" 답게 아쉬운 점도 보인다.

물론 아래 아쉬운 점들이 팀 모두가 Windows 환경에서만 개발할 경우엔 이슈가 아닐 수 있다. 
다시 말해 아래 항목들은 개발팀이 Windows/Linux Cross-Platform 환경에서 개발할 때 문제 소지가 있는 것들이다.

1) 생성되는 파일명이 hash 기반이다

아래 그림은 개인적으로 진행하는 프로젝트에서 생성된 unity 빌드 파일들이다.


unity_xxx.cpp 파일들을 생성하면서 xxx에 대한 명명규칙이 hash 기반이다 보니, 프로젝트 구성(파일 추가/삭제 등)이 변경될 때마다 생성되는 파일들의 이름이 싹 바뀌어 버린다.

Windows 환경에서 누군가 Unity 빌드를 생성해 내었다고 치자.
이 결과물의 잇점을 Linux 환경에서도 누릴려면, 생성되는 unity_xxx.cpp 파일들이 소스 컨트롤 하에 관리될 수 있어야 한다.
헌데 매번 파일명이 싹 바뀌어버리다 보니, 이것을 SCM으로 관리하는 것이 만만치가 않다.

2) cpp 파일들이 절대경로로 포함된다

이 역시 팀단위 1)의 경우와 결과적으로 유사한 팀단위 작업의 어려움을 만들어 낸다.

도대체 무슨 생각으로 절대경로로 처리했는지 이해가 되지 않지만, 누구나 쉽게 이슈 제기를 할 수 있는 부분이기에 1번 항목보다 빠르게 보완될 것이라 생각한다.


1 2 3 4 5 6 7 8 9 10 다음