CMake Fundamentals for Building C++ Projects

CMake is a cross-platform build system generator that simplifies the compilation process for multi-language projects. It generates native build scripts (Makefiles, Visual Studio projects, etc.) from platform-independent configuration files.

Installation

Most Linux distributions include CMake in their package repositories. For Windows or systems without pre-installed CMake, download the latest version from the official website.

# Ubuntu/Debian
sudo apt-get install cmake

# CentOS/RHEL
sudo yum install cmake

Basic Hello World Example

Source Code

// greeting.cpp
#include <iostream>

int main() {
    std::cout << "Hello World" << std::endl;
    return 0;
}

CMake Configuration

# CMakeLists.txt
PROJECT(GreetingApp)

SET(SOURCE_FILES greeting.cpp)

MESSAGE(STATUS "Build directory: ${GreetingApp_BINARY_DIR}")
MESSAGE(STATUS "Source directory: ${GreetingApp_SOURCE_DIR}")

ADD_EXECUTABLE(greeter ${SOURCE_FILES})

Build Process

mkdir build
cd build
cmake ..
make
./greeter

Core CMake Concepts

PROJECT Directive

Specifies the project name and supported languages:

PROJECT(MyProject)           # All languages
PROJECT(MyProject CXX)       # C++ only
PROJECT(MyProject C CXX)     # C and C++

Defines two variables:

  • PROJECT_BINARY_DIR: Build directory path
  • PROJECT_SOURCE_DIR: Source directory path

SET Directive

Defines variables for source files:

SET(APP_SOURCES main.cpp)
SET(APP_SOURCES main.cpp util.cpp)

ADD_EXECUTABLE Directive

Creates executable targets:

ADD_EXECUTABLE(myapp ${APP_SOURCES})

Syntax Rules

  • Variables referenced with ${VARIABLE_NAME}
  • Commands are case-insensitive (convention: uppercase)
  • Parameters separated by spaces or semicolons
  • Filenames with spaces require quotes

External Build Metohdology

Recommended approach to keep source directory clean:

project/
├── CMakeLists.txt
├── src/
└── build/          # Created directory

# Build commands
mkdir build
cd build
cmake ..
make

Project Structure Organization

Directory Layout

project/
├── CMakeLists.txt
├── src/
│   ├── CMakeLists.txt
│   └── main.cpp
├── doc/
│   └── documentation.txt
├── LICENSE
└── README.md

Multi-directory Configuration

Root CMakeLists.txt:

PROJECT(MainProject)
ADD_SUBDIRECTORY(src bin)

src/CMakeLists.txt:

ADD_EXECUTABLE(mainapp main.cpp)

Output Path Configuration

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

Installation Targets

File Installation

INSTALL(FILES LICENSE README.md DESTINATION share/doc/project)

Program Installation

INSTALL(PROGRAMS scripts/launcher.sh DESTINATION bin)

Directory Installlation

INSTALL(DIRECTORY doc/ DESTINATION share/doc/project)

Custom Installation Prefix

cmake -DCMAKE_INSTALL_PREFIX=/custom/path ..

Library Creation

Shared Library

# lib/CMakeLists.txt
SET(LIB_SOURCES utility.cpp)
ADD_LIBRARY(mylib SHARED ${LIB_SOURCES})

Static Library

ADD_LIBRARY(mylib_static STATIC ${LIB_SOURCES})

Library Naming

SET_TARGET_PROPERTIES(mylib_static PROPERTIES OUTPUT_NAME "mylib")
SET_TARGET_PROPERTIES(mylib_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)

Versioning

SET_TARGET_PROPERTIES(mylib PROPERTIES VERSION 1.2 SOVERSION 1)

Library Installation

INSTALL(FILES mylib.h DESTINATION include/mylib)
INSTALL(TARGETS mylib mylib_static
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib)

Using External Libraries

Header Search Paths

INCLUDE_DIRECTORIES(/usr/include/mylib)

Library Linking

TARGET_LINK_LIBRARIES(myapp mylib)

Custom Library Paths

LINK_DIRECTORIES(/custom/lib/path)

Environment Variables

export CMAKE_INCLUDE_PATH=/custom/include/path
export CMAKE_LIBRARY_PATH=/custom/lib/path

Debug Build Configuration

cmake -DCMAKE_BUILD_TYPE=debug ..

Tags: CMake C++ build-systems makefiles cross-platform

Posted on Thu, 18 Jun 2026 17:02:48 +0000 by gamefreak13