C++ CMake Quick Start | Minimal CMakeLists, Libraries & Subprojects

C++ CMake Quick Start | Minimal CMakeLists, Libraries & Subprojects

이 글의 핵심

Compact CMake intro: project(), add_executable, add_library, include paths, conditional tests, and platform flags.

Default CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(MyProject)

set(CMAKE_CXX_STANDARD 17)

add_executable(myapp main.cpp)

Build:

mkdir build
cd build
cmake ..
make
./myapp

Multiple source files

cmake_minimum_required(VERSION 3.10)
project(MyProject)

set(CMAKE_CXX_STANDARD 17)

add_executable(myapp 
    main.cpp
    utils.cpp
    math.cpp
)

Creating a library

# static library
add_library(mylib STATIC
    lib.cpp
    helper.cpp
)

# Dynamic library
add_library(mylib SHARED
    lib.cpp
    helper.cpp
)

# Link to executable file
add_executable(myapp main.cpp)
target_link_libraries(myapp mylib)

Header file path

# Project structure
# project/
#   CMakeLists.txt
#   src/
#     main.cpp
#   include/
#     mylib.h

cmake_minimum_required(VERSION 3.10)
project(MyProject)

include_directories(${PROJECT_SOURCE_DIR}/include)

add_executable(myapp src/main.cpp)

Practical example

Example 1: Basic project structure

MyProject/
├── CMakeLists.txt
├── src/
│   ├── main.cpp
│   ├── math.cpp
│   └── utils.cpp
├── include/
│   ├── math.h
│   └── utils.h
└── build/

CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(MyProject VERSION 1.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# Header file path
include_directories(${PROJECT_SOURCE_DIR}/include)

# Source file list
set(SOURCES
    src/main.cpp
    src/math.cpp
    src/utils.cpp
)

# Create executable file
add_executable(myapp ${SOURCES})

# Compilation options
target_compile_options(myapp PRIVATE
    -Wall
    -Wextra
    -O2
)

Build:

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

Example 2: Using an external library

cmake_minimum_required(VERSION 3.10)
project(MyProject)

set(CMAKE_CXX_STANDARD 17)

# find pthread
find_package(Threads REQUIRED)

add_executable(myapp main.cpp)

# pthread link
target_link_libraries(myapp Threads::Threads)

Example 3: Subdirectory structure

MyProject/
├── CMakeLists.txt
├── app/
│   ├── CMakeLists.txt
│   └── main.cpp
└── lib/
    ├── CMakeLists.txt
    ├── mylib.cpp
    └── mylib.h

Root CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

set(CMAKE_CXX_STANDARD 17)

add_subdirectory(lib)
add_subdirectory(app)

lib/CMakeLists.txt:

add_library(mylib STATIC
    mylib.cpp
)

target_include_directories(mylib PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}
)

app/CMakeLists.txt:

add_executable(myapp main.cpp)
target_link_libraries(myapp mylib)

Advanced features

Conditional compilation

option(BUILD_TESTS "Build tests" ON)

if(BUILD_TESTS)
    add_subdirectory(tests)
endif()

# use
cmake -DBUILD_TESTS=OFF ..

Platform-specific settings

if(WIN32)
    # Windows
    add_definitions(-DWINDOWS)
elseif(APPLE)
    # macOS
    add_definitions(-DMACOS)
elseif(UNIX)
    # Linux
    add_definitions(-DLINUX)
endif()

Build type

# Debug, Release, RelWithDebInfo, MinSizeRel
set(CMAKE_BUILD_TYPE Release)

# use
cmake -DCMAKE_BUILD_TYPE=Debug ..

Installation Rules

# Install executable file
install(TARGETS myapp
    DESTINATION bin
)

# Install header files
install(FILES mylib.h
    DESTINATION include
)

# Install library
install(TARGETS mylib
    DESTINATION lib
)

# use
make install

Frequently occurring problems

Issue 1: Header file not found

Symptom: fatal error: mylib.h: No such file or directory

Cause: Include path not set

dissolvent:

# ❌ No path
add_executable(myapp main.cpp)

# ✅ Add path
include_directories(${PROJECT_SOURCE_DIR}/include)
add_executable(myapp main.cpp)

# ✅ Add by target (more recommended)
target_include_directories(myapp PRIVATE
    ${PROJECT_SOURCE_DIR}/include
)

Symptom: undefined reference to function

Cause: Missing library link

dissolvent:

# ❌ Link not available
add_executable(myapp main.cpp)

# ✅ Library Links
add_executable(myapp main.cpp)
target_link_libraries(myapp mylib)

Issue 3: CMake cache issues

Symptom: Setting changes are not reflected

Cause: Cached settings

dissolvent:

# Delete build directory
rm -rf build
mkdir build && cd build
cmake ..

# Or just delete the cache
rm CMakeCache.txt
cmake ..

Useful commands

Variable output

message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")

Automatically generate file list

file(GLOB SOURCES "src/*.cpp")
add_executable(myapp ${SOURCES})

# recursively
file(GLOB_RECURSE SOURCES "src/*.cpp")

Compiler check

if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
    target_compile_options(myapp PRIVATE -Wall -Wextra)
elseif(MSVC)
    target_compile_options(myapp PRIVATE /W4)
endif()

FAQ

Q1: CMake vs Makefile?

A:

  • CMake: cross-platform, automatic generation
  • Makefile: platform dependent, manually written

Q2: What is an out-of-source build?

A: Separate source and build directories. Recommended.

# out-of-source (recommended)
mkdir build && cd build
cmake ..

# in-source (not recommended)
cmake .

Q3: Which version of CMake should I use?

A: Use at least 3.10 or the latest version if possible.

Q4: How does find_package work?

A: CMake will find the library on your system.

find_package(OpenCV REQUIRED)
target_link_libraries(myapp ${OpenCV_LIBS})

Q5: Multiple build types at the same time?

A: Create multiple build directories.

mkdir build-debug && cd build-debug
cmake -DCMAKE_BUILD_TYPE=Debug ..

mkdir build-release && cd build-release
cmake -DCMAKE_BUILD_TYPE=Release ..

Q6: What are CMake learning resources?

A:

  • Official document: cmake.org
  • Modern CMake: cliutils.gitlab.io/modern-cmake
  • Example: github.com/ttroy50/cmake-examples

Good article to read together (internal link)

Here’s another article related to this topic.

  • C++ CMake Advanced | Multi-target/external library management (large-scale project build)
  • C++ Compilation Process | “Compilation Process” Guide
  • C++ Makefile | “Make Build” Guide

Practical tips

These are tips that can be applied right away in practice.

Debugging tips

  • If you run into a problem, check the compiler warnings first.
  • Reproduce the problem with a simple test case

Performance Tips

  • Don’t optimize without profiling
  • Set measurable indicators first

Code review tips

  • Check in advance for areas that are frequently pointed out in code reviews.
  • Follow your team’s coding conventions

Practical checklist

This is what you need to check when applying this concept in practice.

Before writing code

  • Is this technique the best way to solve the current problem?
  • Can team members understand and maintain this code?
  • Does it meet the performance requirements?

Writing code

  • Have you resolved all compiler warnings?
  • Have you considered edge cases?
  • Is error handling appropriate?

When reviewing code

  • Is the intent of the code clear?
  • Are there enough test cases?
  • Is it documented?

Use this checklist to reduce mistakes and improve code quality.


Keywords covered in this article (related search terms)

This article will be helpful if you search for C++, CMake, Build System, Build, Compile, etc.


  • C++ CMake find_package complete guide | External library integration
  • C++ CMake Targets Complete Guide | Target-based build system
  • CMake error |
  • C++ CMake Advanced | Multi-target/external library management (large-scale project build)
  • C++ vcpkg advanced usage | Manifest·Triplet·Overlay·Binary Cache Guide