[2026] CMake Tutorial for C++: CMakeLists.txt, Targets, and Cross-Platform Builds

[2026] CMake Tutorial for C++: CMakeLists.txt, Targets, and Cross-Platform Builds

이 글의 핵심

Learn CMake for C++ projects: CMakeLists.txt, add_executable, add_library, target_link_libraries, find_package, out-of-source builds, VS Code CMake Tools, and common link errors.

[C++ Hands-On Guide #4] CMake Introduction

Cross-language build tools: compare with Go modules (getting started), Rust/Cargo (intro), and Node/npm (modules). After reading: You can write a minimal CMakeLists.txt, add executables/libraries, link targets, and call find_package for common dependencies. When projects grow, typing long g++ ... lines for dozens of files breaks down. CMake is a build-system generator: you describe what to build in CMakeLists.txt, and CMake emits Makefiles, Ninja files, or IDE projects for each platform. 아래 코드는 mermaid를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// 실행 예제
flowchart LR
  A[CMakeLists.txt] --> B[cmake configure]
  B --> C[Makefile / .sln / Ninja]
  C --> D[Build]
  D --> E[Binaries & libraries]

Previous: #3 VS Code — editor, tasks, debugging. Requirements: CMake 3.10+, g++/Clang or MSVC. Linux/macOS: cmake + a compiler toolchain. Windows: Visual Studio or Build Tools + CMake recommended.

Table of contents

  1. Manual build pain scenarios
  2. Why CMake
  3. Install & concepts
  4. First CMakeLists.txt
  5. Multi-file project
  6. External libraries
  7. VS Code integration
  8. Troubleshooting
  9. Build performance
  10. Production patterns

1. Manual build pain

A three-person team starts with main.cpp, then adds utils.cpp, parser.cpp, … Every new file means editing a giant command line. Windows vs macOS scripts diverge (build.bat vs build.sh). Changing one .cpp may force full rebuilds if your script always compiles everything. CMake tracks dependencies and enables incremental builds.

g++ -std=c++17 -I./include src/main.cpp src/utils.cpp src/parser.cpp \
    src/database.cpp src/network.cpp -L./lib -lsqlite3 -lpthread -o myapp

아래 코드는 mermaid를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

flowchart TB
    subgraph manual[Manual g++]
        M1[Add file] --> M2[Edit command]
        M2 --> M3[Full recompile]
        M3 --> M4[Per-OS scripts]
    end
    subgraph cm[CMake]
        C1[Edit CMakeLists.txt] --> C2[cmake --build]
        C2 --> C3[Incremental compile]
        C3 --> C4[One config, all OSes]
    end

2. Why CMake?

Manual commands don’t scale: -std, -I, -L, -l, different MSVC cl flags on Windows, no reliable incremental builds, and no automatic header dependency tracking. CMake generates native build files, tracks dependencies, integrates with find_package, and works with VS Code, Visual Studio, CLion, etc. 아래 코드는 mermaid를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

sequenceDiagram
    participant Dev as Developer
    participant CMake as CMake
    participant Gen as Generator
    participant Build as Build tool
    Dev->>CMake: cmake ..
    CMake->>CMake: Parse CMakeLists.txt
    CMake->>CMake: Detect toolchain
    CMake->>Gen: Emit Ninja/Make/VS
    Dev->>Build: cmake --build .
    Build->>Dev: Artifacts

3. Install & core concepts

다음은 간단한 bash 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

choco install cmake          # Windows (Chocolatey)
brew install cmake           # macOS
sudo apt install cmake       # Debian/Ubuntu
cmake --version

Terms

  • CMakeLists.txt — what to build.
  • Build directory — e.g. build/, separate from sources (out-of-source build).
  • Generator — Ninja, Make, Visual Studio, …
  • Target — an executable or a library. | | Unix Makefiles | Ninja | |---|----------------|-------| | Speed | OK | Faster parallel builds | | Configure | slower | faster | | Common use | defaults | CI, large trees |
cmake -G Ninja ..
cmake --build .

4. First CMakeLists.txt

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

// g++ -std=c++20 main.cpp -o hello && ./hello
#include <iostream>
int main() {
    std::cout << "Hello, CMake!" << std::endl;
    return 0;
}

CMakeLists.txt 아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// 실행 예제
cmake_minimum_required(VERSION 3.15)
project(HelloCMake VERSION 1.0)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(hello main.cpp)

Build 아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 실행 예제
mkdir build && cd build
cmake ..
cmake --build .
./hello

Debug vs Release (single-config generators):

cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake -DCMAKE_BUILD_TYPE=Release ..

5. Multi-file project (calculator-style)

Layout: 아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

calculator/
├── CMakeLists.txt
├── main.cpp
├── src/operations.cpp
├── src/utils.cpp
├── include/operations.h
└── include/utils.h

CMakeLists.txt (library + executable) 아래 코드는 cmake를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 실행 예제
cmake_minimum_required(VERSION 3.15)
project(Calculator VERSION 1.0)
set(CMAKE_CXX_STANDARD 20)
add_library(calculator_lib STATIC
    src/operations.cpp
    src/utils.cpp
)
target_include_directories(calculator_lib PUBLIC include)
add_executable(calculator main.cpp)
target_link_libraries(calculator PRIVATE calculator_lib)

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

# 실행 예제
mkdir build && cd build
cmake ..
cmake --build .
./calculator 10 + 5

다음은 mermaid를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 실행 예제
flowchart TB
    subgraph sources
        main[main.cpp]
        ops[operations.cpp]
        util[utils.cpp]
    end
    subgraph headers
        oh[operations.h]
        uh[utils.h]
    end
    subgraph artifacts
        lib[calculator_lib]
        exe[calculator]
    end
    ops --> oh
    util --> uh
    ops --> lib
    util --> lib
    main --> exe
    lib --> exe

6. External libraries — find_package

Example: nlohmann/json (adjust install command per OS).

find_package(nlohmann_json 3.11.0 REQUIRED)
add_executable(json_app main.cpp)
target_link_libraries(json_app PRIVATE nlohmann_json::nlohmann_json)

Discovery order (simplified): CMAKE_PREFIX_PATH, system paths, vcpkg/Conan toolchains, Find*.cmake / *Config.cmake.

7. VS Code

  1. Install CMake Tools.
  2. CMake: Select a KitCMake: Configure → build (F7).
  3. Optional .vscode/settings.json: 아래 코드는 json를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
{
    "cmake.configureOnOpen": true,
    "cmake.buildDirectory": "${workspaceFolder}/build",
    "cmake.generator": "Ninja"
}

Enable CMAKE_EXPORT_COMPILE_COMMANDS for IntelliSense with compile commands.

8. Common errors

IssueFix
cmake: command not foundInstall CMake; fix PATH
Version too oldbrew upgrade cmake / snap install cmake
Could NOT find package ...Install dev package; set CMAKE_PREFIX_PATH; vcpkg toolchain
Header not foundtarget_include_directories
undefined referencetarget_link_libraries with correct imported target
Stale cacheDelete build/ and reconfigure
다음은 간단한 mermaid 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
flowchart TD
    A[undefined reference] --> B{Your code or third party?}
    B -->|Yours| C[add_library + link target]
    B -->|Third party| D[find_package + imported target]

9. Build performance

cmake --build . -j$(nproc)        # Linux
cmake --build . -j$(sysctl -n hw.ncpu)  # macOS
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..

Optional: ccache, PCH (target_precompile_headers), parallel jobs.

10. Production patterns

  • Modular trees with add_subdirectory.
  • Use PRIVATE/PUBLIC/INTERFACE intentionally on target_link_libraries.
  • CI: Ninja + ccache, pinned CMake & compiler versions.
  • Shipping libraries: install() rules + Config.cmake for consumers.

See also

Keywords

CMake tutorial, CMakeLists.txt, add_executable, find_package, cross-platform C++, VS Code CMake, Ninja, out-of-source build.

Closing workflow

다음은 간단한 bash 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

mkdir build && cd build
cmake ..
cmake --build .
./myapp

Next: Compilation process (#5)
Previous: VS Code setup (#3)

References

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