미리 컴파일된 헤더( PCH : Pre-Compiled Header)로 컴파일 시간 줄이기
미리 컴파일된 헤더(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"를 입력한다.

위의 방법이 잘못된 이유
VS에서 흔히 저지르는 PCH 에러 해결방법.
아 또 오백만년만에 다시 뵙습니다. 이렇게 글줄 몇자 쓸 시간도 없이, 불철주야로 개발에만 몰두하고 있네요. 오늘 다룰 것은 PCH(Precompiled header)에 관한 에러들입니다. 일단 PCH가 무엇인고 하는
hutsori.tistory.com
문제는 Visual Studio 에서 가끔, 특히 Clean하고 난 이후에 PCH가 먹통이 되고, 컴파일이 안 되는 경우가 있다.
그 중에서, c1083 미리 컴파일된 헤더 파일을 열 수 없습니다.(c1083 cannot open precompiled header file) 이게 사람 환장하게 만들죠.
이 에러에 대해 msdn문서를 찾아보면, 결국 pch파일이 생성되지 않았다./pch파일이 존재하지 않는다. 에 결론이 도달하게 되고, 실제로도 pch파일이 생성되지 않는 모습을 보실 수 있는데요,
여지껏 잘 쓰다가 갑자기 저렇게 안 되는 경우,
- 흔히 Project Properties에서 C/C++탭을 열고,
- Precompiled Headers 를 선택하고,
- /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를 사용하는 데에 조금 더 도움이 되시기를 빕니다.
결론
- PCH 설정은 pch.cpp(또는 stdafx.cpp) 파일만 /Yc 옵션 적용한다. 그 외의 파일에는 PCH관련 옵션 적용 금지
- 모든 cpp파일은 pch.h(또는 stdafx.h)를 포함시켜서 사용해도 괜찮다
Intel Compiler 뭐같음.
출처: https://hutsori.tistory.com/48 [(주)헛소리 공식 블로그]