본문 바로가기
IT 공부/Visual Studio 툴 사용하기

[Visual Studio] - 소스파일과 빌드 산출물을 깔끔하게 구성하는 방법

by exdus3156 2024. 12. 23.

 

< 개괄 >
- 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 ] 파일의 내용을 토대로 분류를 시각화한 결과일 뿐이다.

 

Project.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 폴더 내부

 

Src 폴더 내부는 각 프로젝트로 분류된 폴더와 sln을 배치했다. 따라서 엄밀히 따지자면 VS에게는 여기가 솔루션의 루트 디렉터리로 인식된다. 각 프로젝트는 무조건(!) 반드시(!) 소스코드만 들어가도록 설계했다. 즉, 빌드된 결과물들이 소스코드 폴더와 섞이면 안 되도록!.

 

Build, Output 폴더 구조.

 

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에 동기화되는 것이다.