CMake from Beginner to Pro (1): A Minimal Introduction to CMake – Environment Setup and First Project

CMake from Beginner to Pro (1): A Minimal Introduction to CMake - Environment Setup and First Project

1. Why Use CMake?

In C++ projects, manually managing the build chain (especially for large projects with multiple platforms and modules) can introduce significant complexity. CMake addresses the following issues with its declarative syntax:

  • Cross-platform builds: Generates build files for the corresponding platform (Makefile/MSVC project/Xcode project)

  • Dependency management: Automatically finds third-party libraries (such as OpenCV, Boost)

  • Modular design: Supports multi-level directories, isolation of dynamic/static libraries

2. CMake Installation Guide on Ubuntu

2.1 Basic Installation (Recommended for Beginners)

Install the default repository version via APT:

sudo apt update && sudo apt install cmake
cmake --version  # Verify version (Ubuntu 22.04 provides 3.22.1 by default)

2.2 Install the Latest Version (Recommended for Developers)

Install the latest CMake from the Kitware official repository:

# Add Kitware repository
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null
# Install CMake
sudo apt update && sudo apt install cmake cmake-curses-gui
cmake --version  # Verify version (should be ≥3.28)

3. Core Command Details

3.1 <span>cmake_minimum_required()</span>: Version Constraint

Function Definition:

cmake_minimum_required(VERSION <min> [FATAL_ERROR])
  • Purpose: Declares the minimum compatible version of CMake to avoid syntax compatibility issues.

  • Example:

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)  # Exit with error if below 3.10

3.2 <span>project()</span>: Define Project Metadata

Function Definition:

project(<PROJECT-NAME>     [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]     [LANGUAGES <language-name>...])
  • Key Parameters:

    • <span>VERSION</span>: Project version number (affects variable<span>PROJECT_VERSION</span>)

    • <span>LANGUAGES</span>: Specify languages (e.g.,<span>CXX</span>,<span>C</span>,<span>CUDA</span>)

  • Example:

project(HelloCMake     VERSION 1.0.0     LANGUAGES CXX CUDA  # Supports C++ and CUDA, can be omitted)

3.3 <span>add_executable()</span>: Generate Executable File

Function Definition:

add_executable(<target> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 [source2 ...])
  • Parameter Description:

    • <span><target></span>: Executable file name (e.g.,<span>hello</span>)

    • <span>EXCLUDE_FROM_ALL</span>: Exclude from default build (must be specified manually for generation)

  • Example:

add_executable(hello_main     src/main.cpp     src/utils/logger.cpp)

3.4 <span>aux_source_directory()</span>: Collect Source Files

Function Definition:

aux_source_directory(<dir> <variable>)
  • Purpose: Automatically collects all source files in the directory (<span>.c</span>,<span>.cpp</span>, etc.) into a variable.

  • Issue: May mistakenly include header files (<span>.h</span>), recommended to use<span>file(GLOB)</span><span>:</span>

file(GLOB SRC_FILES     CONFIGURE_DEPENDS     "src/*.cpp"  # Use GLOB_RECURSE for recursive matching)

4. Practical: Build Your First CMake Project

4.1 Project Structure

HelloCMake/  ├── CMakeLists.txt  ├── include/  │   └── utils.h  └── src/      ├── main.cpp      └── utils.cpp  

4.2 Write CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(HelloCMake VERSION 1.0.0 LANGUAGES CXX)
# Collect source files (recommended to declare explicitly)
file(GLOB SRC_FILES     CONFIGURE_DEPENDS     src/*.cpp)
# Generate executable file
add_executable(hello_main     ${SRC_FILES})
# Include header file paths (recommended modern CMake way)
target_include_directories(hello_main     PRIVATE         ${PROJECT_SOURCE_DIR}/include  # Only used by the current target)
# Set C++ standard
set_target_properties(hello_main PROPERTIES     CXX_STANDARD 17    CXX_STANDARD_REQUIRED ON)

4.3 Build and Run

# Create build directory (isolate source and generated files)
mkdir -p build && cd build
# Generate build system (default Debug mode)
cmake ..  
# Compile and run
make -j$(nproc)  ./hello_main

5. Key Debugging Techniques

5.1 View Variable Values

message(STATUS "Source files: ${SRC_FILES}")  # Print variable content

5.2 Graphical Configuration (Optional)

In the Ubuntu development environment, it is recommended to use the command line as much as possible to reduce GUI usage.

ccmake ..  # Command line interactive interface
cmake-gui  # Graphical interface

6. Summary and Next Article Preview

Key Points of This Article:

  • Master CMake environment configuration and basic syntax

  • Understand core commands such as<span>project()</span> and <span>add_executable()</span>

  • Build the first executable file and verify it

Next Article Preview:

  • “Part 2: Variables and Scope – The Cornerstone of CMake Programming”

    • Variable definitions and scope rules

    • Environment variables and cache variables

    • Dynamic configuration of project parameters

    • Hands-on Practice: Try modifying <span>CMakeLists.txt</span>, add new <span>.cpp</span> files and rebuild, observe the output changes.Feedback: Feel free to leave comments in the discussion area regarding any issues encountered during the build!

For source code, please refer to:

https://github.com/vinmanager/hellocmake

Leave a Comment