CMakeLists.txt vs .cmake
Prerequisites
- Basic understanding of CMake workflow (Configure → Build → Install)
cmake -S . -B build
. Why CMake Structure Matters
In small projects, a single CMakeLists.txt is often enough.
However, in real-world or large-scale projects (e.g., OpenCV), the build configuration becomes too complex to maintain in a single file.
To solve this, CMake supports **modularization using `.
2. Core Concep
1
2
| CMakeLists.txt = Entry Point
.cmake = Modular Components
|
CMakeLists.txt → main control file.cmake → reusable logic, functions, and configurations
| Command | Purpose |
|---|
| include | load reusable logic |
| add_subdirectory | add build unit |
3. CMakeLists.txt
3-1. Role
- Starting point of the project
- Defines build targets
- Controls overall flow
3-2. Example
1
2
3
4
5
6
| cmake_minimum_required(VERSION 3.10)
project(MyApp)
include(cmake/utils.cmake)
add_executable(MyApp main.cpp)
|
3-3. Key Characteristics
- Required in every directory that participates in the build
- Can exist in multiple directories
- Connected via:
1
| add_subdirectory(subdir)
|
4. .cmake Files
4-1. Role
- Split complex logic into reusable modules
Store:
- variables
- functions / macros
- configuration rules
4-2. Example
1
2
3
4
5
6
7
| # cmake/utils.cmake
set(CMAKE_CXX_STANDARD 17)
function(print_message msg)
message(${msg})
endfunction()
|
4-3. Usage
1
| include(cmake/utils.cmake)
|
include() does NOT import like a module. It executes the file in-place.
1
2
3
4
5
6
7
8
9
10
11
12
| cmake_minimum_required(VERSION 3.10)
project(MyApp)
-------include(cmake/utils.cmake) part---------
set(CMAKE_CXX_STANDARD 17)
function(print_message msg)
message(${msg})
endfunction()
-----------------------------------------------
add_executable(MyApp main.cpp)
|
- Executes code directly
Used for:
5. Typical Large Project Structure
1
2
3
4
5
6
7
8
9
10
| project/
├── CMakeLists.txt
├── cmake/
│ ├── utils.cmake
│ ├── options.cmake
│ └── install.cmake
├── src/
│ └── CMakeLists.txt
└── lib/
└── CMakeLists.txt
|
1
2
3
4
5
6
7
8
9
| CMakeLists.txt
↓
include(.cmake files)
↓
add_subdirectory(...)
↓
Multiple CMakeLists.txt executed
↓
Single build graph generated
|
6. Why Use .cmake Files?
Without modularization:
1
2
3
4
5
| # thousands of lines in one file
set(...)
if(...)
foreach(...)
install(...)
|
With .cmake:
1
2
3
| include(options.cmake)
include(compiler.cmake)
include(install.cmake)
|
1
2
3
4
5
| ✔ CMakeLists.txt is the entry point
✔ .cmake files are modular building blocks
✔ include() executes code inline
✔ add_subdirectory() links multiple build units
✔ Large projects rely heavily on .cmake modularization
|