[2026] C++20 Modules: Escape Include Hell and Speed Up Builds with import

[2026] C++20 Modules: Escape Include Hell and Speed Up Builds with import

이 글의 핵심

C++20 modules: export module, import, partitions, global module fragments, CMake 3.28 FILE_SET MODULES, GCC/Clang/MSVC workflows, common errors, and incremental migration from headers.

Introduction: “Including headers makes builds too slow”

One large header pulls in dozens more; every .cpp parses that text again. Modules parse once and reuse BMIs (e.g. .pcm)—major compile-time wins at scale. Requirements: C++20, GCC 11+, Clang 13+, MSVC 2019 16.10+; CMake 3.28+ has solid FILE_SET ....MODULES support.

What is a module?

A module is a translation unit with an export module (or implementation module name;) that exposes only exported declarations to import consumers—unlike textual #include paste.

Global module fragment

아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.

module;
#include <vector>   // only in this preamble
export module mylib;
export int add(int a, int b) { return a + b; }

Header vs module (concept)

#includeimport
UnitText pasteParsed BMI cache
Duplicate workPer TUOnce per module
MacrosLeak everywhereContained

Partitions

Split large modules: export module mylib:part1;, aggregate with export import mylib:part1; in the primary interface.

Build commands (sketch)

  • GCC: -std=c++20 -fmodules-ts, compile interface units first in dependency order.
  • Clang: often -std=c++20 -c file.cppm.
  • MSVC: /std:c++20 and /interface for .ixx.

CMake 3.28+

아래 코드는 cmake를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

target_sources(app PRIVATE FILE_SET all MODULES
    math.cppm
    geometry.cppm
    geometry_impl.cpp
)

Common errors

  1. Module not found / link order—build interface .o before importers.
  2. export inside module; preamble—illegal.
  3. Using non-exported symbols from another module.
  4. Circular imports—split interfaces or introduce a third module.
  5. #include before import can pollute macros—prefer import first.
  6. Wrong extension—use .cppm / .ixx for interface units.
  7. Wrong partition compile order.
  8. export in implementation unit—only primary/partition interfaces export.

Performance (illustrative)

Large projects often see ~50–75% compile-time reduction versus repeated header parsing—depends on project shape and compiler.

Production patterns

  • Migrate new code first; keep #include where needed.
  • PIMPL + modules for ABI stability.
  • Wrap import std gaps with thin module shims until the toolchain supports import std.
  • Cache .pcm paths in CI.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3