Visual Studio C++ Slow Build — Complete Guide
이 글의 핵심
Visual Studio C++ slow build Visual, Studio, C++, Introduction: "10-minute build...
Introduction: “10-Minute Build…Coffee Break”
When building C++ projects in Visual Studio, compilation time increases exponentially as files grow. Especially when header files have many templates/inline functions or deeply nested #include, full builds can take minutes to tens of minutes. This guide organizes 10 practical methods to improve Visual Studio C++ compilation speed.
What This Guide Covers:
- Precompiled Header (PCH): Pre-compile frequently used headers
- Parallel Build (/MP): Utilize multiple CPU cores
- Incremental Link: Re-link only changed parts
- Forward Declaration: Remove unnecessary includes
- C++20 Modules: Replace headers with
import - ccache: Accelerate rebuilds with compilation cache
- Other project setting optimizations
Required Environment: Visual Studio 2019/2022 (Windows). PCH·/MP·incremental link applied in VS project/CMake settings. C++20 modules·ccache are optional, guided based on respective tools.
Reality in Production
When learning development, everything is clean and theoretical. But production is different. You wrestle with legacy code, chase tight deadlines, and face unexpected bugs. The content covered in this guide was initially learned as theory, but I realized “ah, that’s why it’s designed this way” while applying it to actual projects.
What stands out in my memory is the trial and error from my first project. I did it as I learned from books but spent days not knowing why it didn’t work. Eventually, I found the problem through a senior developer’s code review and learned a lot in the process. This guide covers not only theory but also pitfalls you may encounter in practice and their solutions.
1. Use Precompiled Header (PCH)
What is PCH?
Precompiled Header (PCH) is a technique that pre-compiles frequently used but unchanging headers (e.g., <iostream>, <vector>, <boost/asio.hpp>) and reuses them in each .cpp file. Saves time parsing and compiling same headers repeatedly.
Why is it so effective?
C++ header files have many nested includes. For example, including <iostream> internally includes dozens of other headers. If project has 100 .cpp files and each includes <iostream>, same header is parsed 100 times. With PCH, parse once and reuse result.
Concrete Effects:
- Boost.Asio include: 2-3 seconds per file → 0.1 seconds with PCH
- Qt include: 5-10 seconds per file → 0.2 seconds with PCH
- 100-file project: 5 minutes → 2 minutes (60% reduction)
Caution:
Only include rarely changed headers in PCH. Including frequently modified project headers can make it slower as PCH must be regenerated.
Setup in Visual Studio
1. Create pch.h file:
Here is detailed implementation code using C++. Import the necessary modules. Understand the role of each part while examining the code.
// pch.h
#ifndef PCH_H
#define PCH_H
// Frequently used standard library
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <algorithm>
// External libraries
#include <boost/asio.hpp>
#include <fmt/core.h>
#endif
2. Create pch.cpp file:
// pch.cpp
#include "pch.h"
3. Project property settings:
- pch.cpp: Properties → C/C++ → Precompiled Headers → Create Precompiled Header (/Yc)
- All other .cpp: Properties → C/C++ → Precompiled Headers → Use Precompiled Header (/Yu), Precompiled Header File:
pch.h
4. Include at top of each .cpp file:
#include "pch.h" // ✅ Always first line
#include "myheader.h"
// ...
Effect
Depending on project size, 30-70% compilation time reduction is possible. Especially effective when using heavy header libraries like Boost, Qt.
2. Enable Parallel Build (/MP)
/MP Option
By default, Visual Studio compiles one .cpp file at a time. Enabling /MP option uses multiple CPU cores for parallel compilation.
Why not default?
Historical reasons. Old days had mostly single-core CPUs, and parallel compilation consumes much memory. Nowadays most have 4+ cores, so enabling /MP is almost always beneficial.
How much faster?
Theoretically scales with core count, but in practice:
- 4 cores: 2-3x
- 8 cores: 3-5x
- 16 cores: 4-7x
Not perfectly linear because link stage is not parallelized and some files take much longer creating bottlenecks.
Setup Method
Project properties:
- C/C++ → General → Multi-processor Compilation → Yes (/MP)
Or command line:
msbuild MyProject.sln /p:CL_MPCount=8
CMake:
if(MSVC)
add_compile_options(/MP)
endif()
Effect
2-4x build speed improvement possible on 4+ core CPUs. However, memory usage also increases, so can become slower if RAM is insufficient.
3. Enable Incremental Link (/INCREMENTAL)
What is Incremental Link?
Incremental Linking is a technique that re-links only changed object files. Link time greatly reduced by not re-linking entire program.
Setup Method
Project properties:
- Linker → General → Enable Incremental Linking → Yes (/INCREMENTAL)
CMake:
if(MSVC)
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /INCREMENTAL")
endif()
Caution
- Recommended only for debug builds. For release builds, better to do full link for optimization.
- Sometimes incremental link info gets corrupted causing strange errors. In this case, Clean Solution then rebuild.
4. Reduce includes with Forward Declaration
Problem Situation
Header (MyClass.h):
Below is an implementation example using C++. Import the necessary modules and define a class to encapsulate data and functionality. Try running the code directly to check its operation.
#include "HeavyClass.h" // ❌ Include entire HeavyClass definition
class MyClass {
HeavyClass* member; // Only using pointer, don't need full definition
};
If HeavyClass.h is heavy and many files include it, compilation time increases.
Solution: Forward Declaration
Below is an implementation example using C++. Define a class to encapsulate data and functionality. Try running the code directly to check its operation.
// MyClass.h
class HeavyClass; // ✅ Forward declaration
class MyClass {
HeavyClass* member; // Pointer/reference OK with just forward declaration
};
Include actual definition only in MyClass.cpp:
Below is an implementation example using C++. Import the necessary modules. Try running the code directly to check its operation.
// MyClass.cpp
#include "MyClass.h"
#include "HeavyClass.h" // Include here
void MyClass::someMethod() {
member->doSomething(); // OK
}
Summary
Key Points
- PCH: Pre-compile frequently used headers
- Parallel build (/MP): Use multiple cores
- Incremental link: Re-link only changes
- Forward declaration: Reduce includes
- Unity build: Combine multiple files
- C++20 modules: Modern alternative to headers
Build Time Reduction
| Method | Effect | Difficulty |
|---|---|---|
| PCH | 30-70% | Easy |
| /MP | 2-4x | Very Easy |
| Incremental link | 50-80% | Easy |
| Forward declaration | 10-30% | Medium |
| Unity build | 50-90% | Medium |
| C++20 modules | 70-90% | Hard |
Best Practices
- ✅ Always enable PCH and /MP
- ✅ Use incremental link in debug builds
- ✅ Use forward declarations when possible
- ❌ Don’t put changing headers in PCH
- ❌ Don’t ignore RAM usage with /MP
Related Articles
- C++ Compile-Time Optimization
- C++ LNK2019 Error
Master build optimization for faster C++ development! 🚀
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. Everything about Visual Studio C++ Slow Build : configuration, optimization, troubleshooting. Understand build systems p… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- C++ 컴파일 시간 최적화 | 모듈·PCH·ccache·분산 빌드 [#51-5]
- C++ LNK2019 | ‘unresolved external symbol’ 링커 에러 원인 5가지와 해결법
- C++ 컴파일 타임 최적화 | constexpr·PCH·모듈·ccache·Unity 빌드 [#15-3]
이 글에서 다루는 키워드 (관련 검색어)
C++, Visual Studio, compile-speed, build-optimization, PCH, precompiled-header, parallel-build 등으로 검색하시면 이 글이 도움이 됩니다.