프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by 친절한티스
지루한 컴파일 시간 조금이라도 줄여보자
코딩을 하다 보면 프로젝트의 몸집이 커지게 되고, 그에 비례하여 컴파일 타임도 기하급수적으로 늘어나게 됩니다. 단지 코드 몇줄 수정하고 추가 했을 뿐인데 매번 컴파일 타임이 수분~수십분 걸리게 되면 작업의 리듬도 깨지게 되고 프로그래머의 능률은 저하되게 되죠. 그래서 빌드 타임을 최소화 하기 위한 여러 기법들이 있습니다. 인크레디 빌드 IncrediBuild 같은 서드 파티의 도움을 받을 수도 있고, 오늘 소개 해드릴 미리 컴파일 된 헤더를 사용하는 방법등이 있습니다. 

 
미리 컴파일 된 헤더(Precompiled Header)는 무엇인가요?
단어 그대로 헤더 파일들을 미리 컴파일 해두는 것입니다. 미리 컴파일 된 헤더를 만들면 pch 라는 파일이 생성 되는데 컴파일러는 이를 참조하여 프로젝트 컴파일을 수행하게 됩니다. 미리 컴파일 시킨 헤더를 참조하니 기존에 헤더 파일을 일일히 파싱하던 때에 비해서 컴파일 속도가 빠른 것 입니다.

미리 컴파일된 헤더 파일을 사용하는 메이크파일의 구조
이미지 출처 : MSDN

미리 컴파일된 헤더를 사용하는 방법은 간단합니다. 일단 미리 컴파일 된 헤더로 사용될 헤더 파일(.h)과 소스 파일(.cpp)을 프로젝트에 추가 합니다. ( 이하 Visual Studio 기준 )


그 다음 프로젝트 속성에 들어가 미리 컴파일 된 헤더를 사용하겠다는 설정 해줍니다.
 


추가한 cpp 파일의 속성 메뉴에 들어가 미리 컴파일 된 헤더 만들기를 설정 해줍니다. 이를 통해 Precompiled.h 파일에서 참조 하고 있는 헤더 파일들을 미리 컴파일 하게 됩니다.



이로서 미리 컴파일 된 헤더 사용 하기의 준비는 모두 끝났습니다.

어떤 헤더 파일을 미리 컴파일 시켜야 할까?
앞서 미리 컴파일된 헤더를 쓰면 빌드 타임이 줄어든다고 했습니다. 그렇다면 많은 헤더들을 추가 하면 좋을까요? 결론은 아닙니다. 미리 컴파일 된 헤더에 포함 시킬 헤더를 선정하는 것은 신중 해야 합니다. 예로 미리 컴파일 된 헤더에 포함된 파일이 수정이 일어나면 미리 컴파일 된 헤더도 새로 만들게 됩니다. 이렇게 되면 미리 컴파일 된 헤더를 사용하는 의미가 없어집니다. MSDN을 보면 다음 사항에 미리 컴파일된 헤더 파일 사용을 권장하고 있습니다.

  • 자주 바뀌지 않고 크기가 큰 코드 본문을 항상 사용합니다.
  • 프로그램이 여러 개의 모듈로 구성되어 있으며, 모든 모듈이 포함 파일의 표준 집합 및 동일한 컴파일 옵션을 사용합니다. 이 경우 모든 포함 파일을 미리 컴파일해서 하나의 미리 컴파일된 헤더로 만들 수 있습니다.

여기서 핵심은 자주 바뀌지 않고라 할수 있습니다. 대표적으로 STL 헤더 같은 것을 생각할 수 있습니다. 이들의 헤더 파일은 거의 바뀔일이 없죠. 그 외에 프로젝트에 사용하는 서드파티 라이브러리 헤더 파일이라든가 한번 만들어두고 수정할일 없는 헤더 파일이 있는 경우 추가해주면 좋습니다. 실제로 사용 예제 코드를 살펴 보겠습니다.

// Precompiled.h
#pragma once
#include <string>
#include <vector>
#include <list>

// Precompiled.cpp와 미리 컴파일된 헤더를 사용하는 프로젝트의 모든 cpp 파일에 추가
#include "Precompiled.h"

위와 같이 헤더 파일을 추가 해 되면 string, vector, list 헤더 파일은 미리 컴파일 되게 됩니다. 이로 인해 생기는 이점이 하나 더 있습니다. vector와 list를 사용할때 일일히 #inlcude <vector> 를 추가할 필요가 없어지는 겁니다. 간단히 이야기 해 #include <vector> 구문이 전역적으로 적용되는 것과 같은 효과가 발생하게 됩니다.

자그마한 관심으로 컴파일 시간이 줄어들수 있습니다

미리 컴파일된 헤더를 사용하는 것 외에도 작은 습관 하나로 컴파일 타임을 줄이는 법도 있습니다. 다음과 같이 헤더 파일이 있다고 가정해보겠습니다.

// Foo.h
#include "Bar.h"
class Foo
{
private:
	Bar mBar;
};

Foo라는 클래스에서 Bar 클래스를 멤버 변수로 가지고 있습니다. 이를 위해 Bar 클래스가 선언 되어있는 헤더 파일을 포함하고 있습니다. 그런데 어느 순간 Bar 클래스가 수정되었다고 가정해보겠습니다. 그러면 컴파일 시에 Bar 헤더를 포함해 Foo 헤더까지 재 컴파일을 하게 됩니다. 어찌 보면 당연한 결과지만 작은 수정을 통해 이를  방지할 수 있는 방법이 있습니다.

// Foo.h
class Bar;
class Foo
{
private:
	Bar *mpBar;
};

// Foo.cpp
#include "Bar.h"

바뀐 부분을 보시면 Bar 멤버변수가 포인터로 변했고, include 를 안하는 대신 전방 선언을 넣었습니다. 그리고 Bar 클래스를 사용하는 본문 파일에 include를 추가하였습니다. 이렇게 변환 하였을 경우 Bar 클래스의 수정이 일어나도 Foo.h 파일은 재 컴파일이 일어나지 않게됩니다. 컴파일 타임이 줄어 드는 것이죠.

참조
미리 컴파일된 헤더를 사용하자
MSDN 미리 컴파일된 헤더 파일 만들기
빌드 시간에 관한 고찰

댓글을 달아 주세요

  1. Favicon of http://bluekms21.blog.me 크로스 2012.03.17 20:46  댓글주소  수정/삭제  댓글쓰기

    미리 컴파일된 해더.. 저도 자주 쓰고있지요..ㅎ
    유니티빌드라던가 하는 거창함 없이 바로 적용할 수 있어서 좋은 강좌인것 같습니다. ^ㅡ^

  2. Favicon of http://blog.wimy.com zelon 2012.03.19 01:06  댓글주소  수정/삭제  댓글쓰기

    Incredibuild 에서는 precompiled header 쓰면 경고 같은게 나오는 경우도 있었던듯... 그래도 precompiled header 가 짱!! 아.. 참고로 gcc 에서도 요즘 버젼에는 precompiled header 지원해줍니다~

    그리고 질문하나... 혹시 불필요하게 include 된 파일을 찾아주는 툴 같은거 있을까요?... 있으면 참 좋은데 ㅠㅜ

  3. Favicon of http://lunapiece.net Lyn 2012.03.19 10:12  댓글주소  수정/삭제  댓글쓰기

    프리컴파일헤더는 템플릿 떡칠을하게되는 상황에선 별 도움이 안되더라구요...

    유니티 빌드가 현실적으로 더 나은듯 ㅡㅜ
    물론 혼용하지 못하란법은 없지만

  4. 아르케스후스 2015.05.12 00:23  댓글주소  수정/삭제  댓글쓰기

    ... 템플릿은 타입마다 다른 코드를 생성해야해서 의미가 없어요. 탬플릿을 오브젝트로 만들 수 없다는 것만 생각해도 뻔히 나오지 않나?
    pch가 뭔지 설명한건 좋은데 템플릿 들이데면서 잘못된 정보로 구글 페이지 랭크 더럽히지 마세요

    • 지나가던선비 2016.02.25 13:00  댓글주소  수정/삭제

      한국말로 좀 얘기하세요..

    • ㅇㅇ 2017.03.30 09:22  댓글주소  수정/삭제

      http://stackoverflow.com/questions/688053/what-to-put-in-precompiled-header-msvc
      읽어보세요 템플릿 코드를 미리 오브젝트로 만드는건 아니지만 사용가능합니다