. 미리 컴파일된 헤더

Dangeun 프로젝트부터는 비주얼 C++이 제공하는 미리 컴파일된 헤더 기능(PreCompiled Header:PCH)을 적극적으로 사용한다. PCH는 자주 변경되지 않는 긴 소스를 미리 컴파일하여 그 결과를 별도의 파일에 저장해놓고, 컴파일할 때 이 결과를 사용함으로써 컴파일 속도를 높이는 기법이다. windows.h 같은 큰 헤더 파일을 매번 다시 컴파일하자면 컴파일 속도가 엄청나게 느리기 때문에 미리 컴파일해놓는 것이다.

컴파일러는 처음 컴파일할 때만 PCH를 만들고 이후부터는 헤더 파일의 내용이 바뀌지 않는 한 다시 컴파일하지 않고 PCH의 결과를 사용한다. windows.h를 우리가 직접 편집할 일은 없기 때문에 최초 컴파일할 때만 조금 느리고 두 번째부터는 아주 빠른 속도로 컴파일할 수 있다. C/C++ 언어는 다른 언어에 비해 문법 구조가 복잡해서 컴파일 속도가 느린 것이 큰 결점인데 이 기능으로 인해 대단한 속도 향상 효과를 볼 수 있다. 고급 컴파일러만 제공하는 아주 좋은 기능이므로 적극적으로 활용하도록 하자.

AppWizard(응용 프로그램 마법사)로 프로젝트를 만들면 PCH를 사용하도록 프로젝트 세팅을 자동으로 만들어주는데 Dangeun 프로젝트는 수동으로 만든 것이므로 이 세팅을 직접 해야 한다. 즉 어떤 파일로부터 PCH를 만들고 PCH를 언제 사용할 것인지 컴파일러에게 정보를 제공해야 하는 것이다. stdafx.h 파일은 다음과 같이 작성되어 있다.

 

#define _WIN32_WINNT 0x400

#define _WIN32_WINDOWS 0x401

#include <windows.h>

#include <windowsx.h>

#include <imm.h>

#include <stdio.h>

#include <io.h>

#include <malloc.h>

#include <commctrl.h>

#include <Shlwapi.h>

#include <Shlobj.h>

#include <wininet.h>

#include "Util.h"

#include "resource.h"

#include "ApiEdit.h"

 

파일명을 꼭 stdafx.h로 할 필요는 없지만 비주얼 C++ AppWizard가 이 이름을 사용하고 있으므로 우리도 그렇게 하도록 하자. stdafx.h에는 이 프로젝트에서 사용하는 헤더 파일과 앞으로 사용하게 될 헤더 파일들을 모두 포함시켰다. stdafx.cpp 파일은 다음과 같이 간단하게 작성되어 있다.

 

#include "stdafx.h"

 

이 파일은 아무것도 하지 않으며 오로지 stdafx.h만 인클루드하고 있는데 컴파일러가 이 파일을 컴파일할 때 PCH를 만들도록 할 것이다. 솔루션 탐색기의 stdafx.cpp 파일(stdafx.h가 아님)에서 팝업메뉴를 열고 속성 항목을 선택해보자. 왼쪽의 옵션 트리에서 C/C++/미리 컴파일된 헤더 항목을 선택하면 PCH 관련 옵션이 나타난다.

미리 컴파일된 헤더 만들기/사용 옵션이 그림과 같이 미리 컴파일된 헤더 만들기/(Yc)로 선택되어 있다. 이 옵션이 지정되면 stdafx.cpp를 컴파일할 때 이 파일에 인클루드된 모든 헤더 파일을 컴파일하여 PCH 파일을 미리 만들어 놓게 된다. stdafx.cpp stdafx.h를 포함하고 있고 stdafx.h에는 자주 변하지 않는 모든 헤더 파일이 포함되어 있으므로 이 헤더 파일들이 미리 컴파일될 것이다.

ApiEdit.cpp Dangeun.cpp, Util.cpp stdafx.cpp를 제외한 나머지 모듈들의 속성창을 띄워 이 옵션을 확인해보면 미리 컴파일된 헤더 사용/(Yu) 옵션이 선택되어 있다. 즉 이 파일들을 컴파일할 때는 처음부터 컴파일하지 말고 stdafx.h로부터 만들어진 PCH파일을 참조하라는 뜻이다.

이렇게 설정해놓고 컴파일하면 windows.h, commctrl.h, stdio.h 등의 큰 헤더 파일이 딱 한 번만 컴파일되므로 컴파일 속도가 엄청나게 빨라지게 된다. 앞으로는 필요한 헤더 파일들을 모두 stdafx.h에서 인클루드하고 나머지 모듈들은 stdafx.h만 인클루드하면 된다. 이렇게 하면 헤더 파일이 여러 번 인클루드되지 않아 좋고 헤더 파일끼리의 포함 순서에 신경쓸 필요도 없고 PCH 기능을 활용하므로 컴파일 속도도 빨라지고 여러 모로 해피해진다. ApiEdit.cpp는 미리 컴파일된 헤더 기능을 사용하기 위해 다음과 같이 수정되었다.

 

//#define _WIN32_WINNT 0x400

//#define _WIN32_WINDOWS 0x401

//#include <windows.h>

//#include <windowsx.h>

//#include <imm.h>

//#include <stdio.h>

//#include <io.h>

//#include <malloc.h>

//#include <commctrl.h>

//#include <Shlwapi.h>

//#include <Shlobj.h>

//#include <wininet.h>

//#include <stdio.h>

//#include "ApiEdit.h"

#include "stdafx.h"

 

stdafx.h ApiEdit.cpp를 컴파일하기 위한 모든 헤더가 다 포함되어 있기 때문에 다른 헤더 파일은 포함시킬 필요가 없으며 stdafx.h만 포함하면 된다. 원래 있던 #include 문은 지우지 않았고 주석 처리만 해두었다. 왜냐하면 ApiEdit는 이 프로젝트뿐만 아니라 PCH를 사용하지 않는 다른 프로젝트에도 사용될 수 있어야 하기 때문이다. 헤더 파일 외에 ApiEdit는 전혀 편집하지 않았으며 ApiEditTest의 것과 동일하다.