C++/C++

미리 컴파일된 헤더( PCH : Pre-Compiled Header)로 컴파일 시간 줄이기

Elan 2021. 3. 4. 00:45

미리 컴파일된 헤더(Pre-complied Header) 란?

자주 사용하지만 거의 변경되지 않는 라이브러리들을 미리 컴파일 해두는 것이다.

즉, #include <모듈명> 과 같은 헤더추가 시 재빌드되는 시간을 줄여 컴파일 시간을 단축하는 목적이다.

 

예를들면 windows.h 같은 덩치가 매우큰 녀석들은 일일히 헤더를 파싱하는것보다 훨씬 빠르겠죠?

 

프로젝트 규모가 커질 수록 전처리기가 컴파일해야될 헤더도 엄청나게 많아진다.

 

이 컴파일 시간을 효과적으로 줄여줄 수 있는 방법을 소개한다. 

 

 

 


흔한 잘못 된 사용 예시

 

아래와 같이 프로젝트 속성에서 PCH를 설정하는 방법은 잘 못된 방법이다.

  예시) 

프로젝트 속성에서 C/C++ 탭 > Precompiled Header > Use(/Yu)로 설정하고,

           stdafx.cpp 파일을 C/C++ 탭 > Precompiled Header > Create(/Yc)로 설정하는 방법

더보기

먼저 흔히 많이들 알고 사용하는 잘못된 방법에 대해서 소개한다.

 

보통 파일명은 stdafx.h 와 stdafx.cpp 을 사용한다.( 기본적으로 Visual C++ 에서 사용하는 PCH 파일 이름이다)

 

1. stdafx.h 와 stdafx.cpp 두 파일을 생성합니다.

 

2. stdafx.cpp 파일만 [  속성 > C/C++ > 미리컴파일된헤더 ] 에서, 미리 컴파일된 헤더 사용(/Yc) 를 선택.

 

주의사항!!대부분의 블로그에서 프로젝트 전체 속성에서 미리 컴파일된 헤더 사용에서 Create(/Yc) 옵션을 적용하는데
이것은 잘못된 방법이다. ( 이유는 맨아래에서 설명 )

 

PCH ( 미리 컴파일할 헤더)의 내용을 입력하기

 

1. stdafx.cpp 파일에 #include "stdafx.h" 를 입력해줍니다.  

 

2. stdafx.h 파일에 미리 컴파일할 헤더를 추가합니다. 

 

3. 작성한 모든 cpp 파일 최상단에 #include "stdafx.h"를 입력한다.

 

 

위의 방법이 잘못된 이유

출처 : hutsori.tistory.com/48

 

 

VS에서 흔히 저지르는 PCH 에러 해결방법.

아 또 오백만년만에 다시 뵙습니다. 이렇게 글줄 몇자 쓸 시간도 없이, 불철주야로 개발에만 몰두하고 있네요. 오늘 다룰 것은 PCH(Precompiled header)에 관한 에러들입니다. 일단 PCH가 무엇인고 하는

hutsori.tistory.com

문제는 Visual Studio 에서 가끔, 특히 Clean하고 난 이후에 PCH가 먹통이 되고, 컴파일이 안 되는 경우가 있다.

 

그 중에서, c1083 미리 컴파일된 헤더 파일을 열 수 없습니다.(c1083 cannot open precompiled header file) 이게 사람 환장하게 만들죠.

 

이 에러에 대해 msdn문서를 찾아보면, 결국 pch파일이 생성되지 않았다./pch파일이 존재하지 않는다. 에 결론이 도달하게 되고, 실제로도 pch파일이 생성되지 않는 모습을 보실 수 있는데요,

 

여지껏 잘 쓰다가 갑자기 저렇게 안 되는 경우, 

  1. 흔히 Project Properties에서 C/C++탭을 열고, 
  2. Precompiled Headers 를 선택하고,
  3. /Yu 옵션이 잘 설정되어 있는 것을 보고 다시 실행시켜 보겠죠?

그러고는 안되서 /Yc를 선택하면 제대로 컴파일 되는 모습도 볼 수 있어요! 야! 신난다!

그게 아니면, "PCH사용 안함"을 선택하라는 것도 있더군요. 이건 진짜 충격과 공포. 이럴거면 왜 굳이 PCH를 쓰는건데?

 

보통 이 문제로 검색하면 이런 방법을 설명해놓고 해답이라는 양 갈겨놨는데,(특히 한글로 된 문서들.)

 

사실 프로젝트 설정에서 /Yc를 쓰는건 PCH를 안 쓰는거랑 같은거에요(...)

 

왜냐면, /Yc옵션은 우리가 "빌드할 때 PCH를 생성하라"는 명령이기 때문이죠.

문제는, 흔히 설정해둔(visual studio default) stdafx.cpp 뿐만 아니라, 

프로젝트 전체에 있는 cpp파일을 전부 PCH로 만들게 되므로,

굉장히 낭비라 할 수 있습니다.

 

여기서 한 발 더 나아가서,

 

Project Properties에서 /Yc 옵션을 쓰고 컴파일 한 후에, 

다시 /Yu로 설정하여 쓰시는 분들도 계시는데,

이 방법으로는 당장 PCH를 쓰는 데에는 지장이 없지만,

다시 Clean하는 경우 /Yu옵션이 작동하지 않게 됩니다.

(당연히 Clean할 때 pch파일도 삭제되므로 사용할 pch파일이 없어지는 거거든요.)

 

그럼 또 /Yc로 바꿔서 컴파일 하고 /Yu로 설정하여 쓸 수도 있습니다만....

이렇게 하는것도 한두번이지 번거로워서 어떻게 이렇게 한답니까.

 

 


올바른 사용방법


올바른 PCH 사용 방법

    1.  프로젝트 속성  [ C/C++ ]    >    [ Precompiled Headers ] 에서 Precompiled Header 는 "Not Using precompiled Headers" 로 설정한다.



    2. stdafx.cpp(Visual Studio에서 default로 사용되는 PCH파일 이름) 파일을 우클릭
        > [ 속성(Properties) ]  >  [ C/C++ ] > [ Precompiled Headers ] > Create(/Yc) 옵션 적용
       ( 다른 파일에는 적용 금지 )

주의사항! 절대 프로젝트 속성에서 Precompiled Header 관련 설정 하지마세요

프로젝트 속성에서 Precompiled Header를 Use(/Yu)로 설정하면 아래와 같은 에러가 뜰것임.

보통 위와 같은 문제는, 자의로든 타의로든 실수로든 stdafx.cpp/stdafx.h파일이 프로젝트에서 이탈(제거)했다가 다시 추가되었을 때,

혹은 PCH를 쓰지 않던 프로젝트의 규모가 커져서 PCH를 써야 할 때 생기는 경우가 대부분인데,

 

위와 같은 방법만 알면, Visual Studio에서 PCH 설정을 좀 더 쉽게 할 수 있습니다.

 

 

사실 이 글을 왜 쓰게 되었나...하면,

 

최근에 Intel Compiler를 쓰고 있어서 "조금 더" 빡치고 있어요.

왜냐하면 Intel Compiler에서는 PCH에러라고 잡지를 않거든요.

 

3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\x64\PlatformToolsets\Intel C++ Compiler XE 13.0\Microsoft.Cpp.x64.Intel C++ Compiler XE 13.0.targets(271,5): error MSB6006: "icl.exe"이(가) 종료되었습니다(코드: 4).

 

에러 메세지가 이모양이니 뭐 어디가 잘못됐나 하고 한참 뒤지기 일쑤입니다.

 

이 메시지가 가리키는 위치에는

 

<ICL Condition="'%(ClCompile.PrecompiledHeader)' != 'Create' and '%(ClCompile.ExcludedFromBuild)'!='true' and '%(ClCompile.UseMSVC)'!='true'"

 

라는 내용이 있는데 여길 봐야 "아 PCH에러구나" 싶죠.

그래도 이게 왜 에러인데? 는 여전히 의문.

MSB6006은 더 의문.(..............거의 대부분은 code 1에 대한 에러에요.)

 

 

그리고 위와 같은 경우가 아니더라도,

 

모든 cpp파일이 "stdafx.h"를 포함하지 않을 때에도 똑같은 에러를 뱉습니다.

정말 환장하죠(.....)

 

결국 Intel Compiler에서는 PCH 에러에 대해서 잘 알려주지 않아서(.....)

이런 삽질을 하게 된 겁니다. 하핳.

 

 

그럼 이 글로 PCH를 사용하는 데에 조금 더 도움이 되시기를 빕니다.

 

 

결론

  1. PCH 설정은 pch.cpp(또는 stdafx.cpp) 파일만 /Yc 옵션 적용한다. 그 외의 파일에는 PCH관련 옵션 적용 금지
  2. 모든 cpp파일은 pch.h(또는 stdafx.h)를 포함시켜서 사용해도 괜찮다
  3. Intel Compiler 뭐같음.



출처: https://hutsori.tistory.com/48 [(주)헛소리 공식 블로그]