< 개괄 >
- Microsoft의 Visual Studio(IDE)는 빌드 산출물을 다소 복잡하게 구성하는 편이다. (주관적)
- 따라서 옵션을 조정해 빌드 결과를 깔끔하게 정리해본다.
- 내용이 사실 굉장히 주관적일 수 있다.
- 원칙은 간단하다. 분류가 내 마음에 들지 않거나, 나에게 필요하지 않으면 과감하게 삭제하자는 것!!
< 해소할 수 있는 궁금증 >
- vcxproj.filter는 무슨 파일인가?
< Visual Studio 프로젝트 생성과 빌드의 문제점 (다소 주관적일 수도..) >
1) 정말로 쓸모가 있는 분류인가?
▷ 화면에 윈도우 창을 하나 출력하는 아주 간단한 프로젝트를 VS에서 생성하면 아래와 같이 배치된다.
▷ VS가 자동으로 만들어준 기초적인 템플릿이다. 많은 파일들이 있으나 VS는 이 파일들을 [리소스 파일], [소스 파일], [헤더 파일]로 분류해준다. [외부 종속성]은 프로젝트가 의존하고 있는 라이브러리들을 헤더 파일들로 보여준다. 그런데 실제 디렉터리의 파일은 아래와 같다.
▷ Visual Studio에서 보는 바와 다르게, 실제 파일들은 필터로 분류되지 않고 한데 뒤섞여 있다.
▷ 게다가 VS의 솔루션 탐색기에서 볼 수 없는 파일 세 가지도 눈에 띈다. 'vcxproj'가 붙은 3개의 파일은 Visual Studio가 프로젝트를 로드하거나 빌드(MSBuild)할 때 참고하는 파일이다. 빌드 시 참고되므로 중요한 파일이지만, 일단 한 번 프로젝트를 세팅하고 나면 관심에서 멀어지는 파일들이기도 하다.
▷ 즉, VS가 파일을 분류한 것은 그저 Visual Studio 소프트웨어가 가상으로 분류한 논리적인 개념일 뿐, 실제 디렉터리와 전혀 다르다. 이와 같은 분류는 VS가 [ ~.vcxproj.filters ] 파일의 내용을 토대로 분류를 시각화한 결과일 뿐이다.
▷ Visual Studio에서 이것저것 솔루션 탐색기의 필터를 배치하고나면 위와 같이 프로젝트의 vcxproj.filters 파일의 내용이 바뀐다. 반대로 이 xml 파일의 내용을 바꾼 뒤에 Visual Studio에서 프로젝트를 로드하면 바뀐대로 시각화해준다. (물론 이 복잡한 xml 파일을 직접 타이핑해서 원하는 구조로 시각화하는 개발자는 없다!)
▷ 문제는 과연 VS가 자동으로 배치해준 구조가 정말로 편의적인지? 여부다. 이것은 사람마다 다를 수 있으나, 보통 헤더파일과 소스코드는 서로 세트로 붙어 다니므로 서로 가까운 곳에 배치되는 것을 선호한다. 다른 개발자들도 이런 방식을 선호한다.
▷ 그래서 위와 같이 분류해도 빌드에 전혀 문제가 없다. 많은 부분을 쳐냈다. 이건 분류를 하지 말라는 것이 아니라, VS가 디폴트로 배치해준 분류가 마음에 들지 않으면 과감하게 삭제해도 괜찮다는 뜻이다. 아래처럼 [외부 종속성] 폴더를 사용 안 함에 체크하면 탐색기에서 해당 항목을 보이지 않게 할 수도 있다. 나는 모듈이 어떤 라이브러리를 사용하고 있는지 파악할 때만 [외부종속성]을 보고 아니면 그냥 끈다. 개발자인 나에게 필요하지 않으니 자유롭게 구성하는 것이다. 어차피 내가 보는 건데!
2) 빌드 산출물 구조가 한눈에 알아보기 힘들다.
▷ VS에서 프로젝트를 갓 생성하면, 실제로 생성되는 솔루션의 내부 디렉터리의 구조는 아래 그림처럼 매우 단순하다.
▷ Visual Studio는 솔루션을 기반으로 하부에 여러 프로젝트를 관리하는 구조다. 빌드해서 최종 실행파일을 완성하는 것도 솔루션 단위로 한다. 그래서 정적 라이브러리나 동적 라이브러리 등 다양한 프로젝트를 한 번에 코딩해서 빌드한다.
▷ 그러면 이 상태에서 빌드하면 어떻게 될까? Debug|x64 모드로 빌드해봤다.
▷ 솔직히 말해, 꽤 당황스러운 폴더 구조가 만들어진다. 크게 보면 아래 두 가지 구조가 생긴다.
1) 중간 산출물 : [MyTestProject] - [x64] - [Debug]
2) 최종 빌드물 : [x64] - [Debug]
▷ 최종 빌드물에 윈도우즈 실행 파일(exe, PE)을 볼 수 있다. 더블 클릭하면 잘 동작한다.
▷ 냉정하게 보면, 나는 빌드된 결과가 배치되는 폴더 구조가 전혀 이해가 가지 않는다. 꽤 많은 윈도우즈 기반의 C/C++ 개발자들도 비슷한 말을 한다. 왜 중간 산출물은 [프로젝트 이름] 폴더에 생성되고, 또 실행 파일은 엇비슷한 이름의 폴더에 배치되는가? 더 이상 이야기하지 말자.. 나도 모른다... 차라리 아래와 같이 바꾸는 것이 이해하기 훨씬 더 편하다.
▷ 우선 최상위 폴더의 내부 구조는 단 세 폴더가 전부다. Build는 최종 빌드 결과물이, Output에는 중간 산출물이, Src는 프로젝트의 소스코드가 들어간다. (※ 최종 빌드 폴더에 Output이란 이름을 붙이는 개발자도 있다. 팀마다, 그리고 사람마다 네이밍은 다를 것이다.)
▷ Src 폴더 내부는 각 프로젝트로 분류된 폴더와 sln을 배치했다. 따라서 엄밀히 따지자면 VS에게는 여기가 솔루션의 루트 디렉터리로 인식된다. 각 프로젝트는 무조건(!) 반드시(!) 소스코드만 들어가도록 설계했다. 즉, 빌드된 결과물들이 소스코드 폴더와 섞이면 안 되도록!.
▷ Build, Output 폴더 모두 빌드를 하고 나면 위와 같이 빌드 모드(Debug|Release & x86|x64)의 4가지 경우에 따라 파일들이 배치되도록 분류했다. 이렇게 하면 편하다. 특히 내 경험상, 링크 과정에서 만나는 대부분의 오류가 Release냐 Debug냐, x64냐 x86이냐 구분을 못하고 서로 맞지 않는 것끼리 링크하려고 해서 생기는 문제였다. 그래서 폴더로 미리 분류하면 정말 편리해진다.
▷ 이렇게 자동화하는 방법은 아래와 같다.
▷ 프로젝트를 오른쪽 클릭해서 속성에 들어간다.
▷ 그러면 출력 디렉터리(실행파일)와 중간 디렉터리를 직접 설정할 수 있는 설정창이 나온다. 이때 반드시 [구성] 항목을 [모든 구성], [모든 플랫폼]으로 설정하는 것을 까먹지 말자. 왜냐하면 지금 모든 경우의 수를 고려하고 있기 때문이다.
- 출력 : $(ProjectDir)\..\..\Build\$(Platform)$(Configuration)\
- 중간 : $(ProjectDir)\..\..\Output\$(Platform)$(Configuration)\$(ProjectName)\
▷ 여기서 $은 VS가 제공해주는 매크로다. Visual Studio에서 정보를 쉽게 찾을 수 있으니 참고.
- ProjectDir : 현재 프로젝트 소스코드가 있는 경로다.
- Plaform : 프로세서 아키텍처 플랫폼(x86, x64)의 문자열이다. x86 아키텍처의 32bit, 64bit를 의미.
- Configuration : 구성(Debug|Release) 문자열이다.
▷ 이렇게 하면 빌드 결과물이 저 경로로 자동으로 배치되어 소스코드 관리가 굉장히 깔끔해진다. 깃 관리에도 유용하다. 소스코드 폴더에 빌드 결과물이 이리저리 뒤섞여 있다면, 깃에 올리거나 제외할 파일을 분류하는 것이 고역일 것이다.
▷ 실제로 초보일 때는 빌드 과정을 전혀 이해하질 못해서, 누군가에게 소스코드를 전달할 때 빌드 결과물마저 통째로 보내는 실수를 겸할 수 있다. 소스코드는 기껏해야 KB단위인데 이게 MB, 심지어 GB이면 뭔가 빌드의 결과물을 제대로 관리하지 못하고 소스코드와 함께 뒤섞어 관리하고 있다는 반증이 아닌가...!!
▷ 지금까지 한 모든 프로젝트 설정은 위와 같이 vcxproj 파일에 xml 형식으로 정리된다. Visual Studio가 내부적으로 사용하는 빌드 도구인 MSBuild가 이 파일을 참고하여 빌드를 수행하는 것이므로 내가 설정한 시스템이 vcxproj에 동기화되는 것이다.
'IT 공부 > Visual Studio 툴 사용하기' 카테고리의 다른 글
[Visual Studio] - 문자 집합 옵션과 UNICODE 매크로 (0) | 2024.12.26 |
---|---|
[Visual Studio] - CRT 런타임 라이브러리의 빌드 방식 (0) | 2024.12.26 |
[Visual Studio] - #include 따옴표(")와 꺾쇠(<>)의 차이 (1) | 2024.12.24 |
[Visual Studio] - 정적 라이브러리와 같이 빌드하기 (0) | 2024.12.24 |
[Visual Studio] - 소스코드를 가져오거나 컴파일할 때 한글 인코딩 문제 (0) | 2024.12.21 |