CMake для C++: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в CMake: что это и зачем нужно

CMake (Cross-Platform Make) — это мощная кроссплатформенная система автоматизации сборки программного обеспечения с открытым исходным кодом. В отличие от традиционных Makefile, CMake не собирает проект напрямую, а генерирует файлы сборки для нативных инструментов (Make, Ninja, Visual Studio, Xcode) на основе простых конфигурационных файлов CMakeLists.txt.

Зачем нужен CMake?

  • Кроссплатформенность: Один и тот же код можно собрать на Windows, Linux и macOS без изменения конфигурации.
  • Управление зависимостями: Встроенная поддержка поиска и подключения внешних библиотек (Boost, OpenCV, Qt и др.).
  • Гибкость: Поддержка различных генераторов проектов (Visual Studio, Xcode, Ninja, Unix Makefiles).
  • Модульность: Возможность создавать библиотеки (статически и динамически), исполняемые файлы и тесты.
  • Интеграция с IDE: Современные IDE (CLion, VS Code, Qt Creator) имеют встроенную поддержку CMake.

CMake стал стандартом де-факто для C++ проектов. Его используют такие гиганты, как Google (TensorFlow, Chrome), Microsoft (VS Code), KDE, LLVM/Clang и многие другие.

Установка CMake

В отличие от Python-библиотек, CMake не устанавливается через pip. Это самостоятельное приложение. Рассмотрим установку для основных ОС:

Windows

  1. Скачайте установщик с официального сайта (выберите версию для Windows — .msi или .zip).
  2. Запустите установку. Обязательно отметьте опцию "Add CMake to the system PATH for all users".
  3. После установки проверьте: cmake --version в командной строке.

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install cmake
cmake --version

macOS (Homebrew)

brew install cmake
cmake --version

Проверка установки

После установки выполните в терминале:

cmake --version
# Вывод должен быть похож на:
# cmake version 3.27.0

Быстрый старт: первый проект на CMake

Создадим простой проект "Hello World" с использованием CMake.

Структура проекта

my_project/
├── CMakeLists.txt
└── main.cpp

Файл main.cpp

#include <iostream>

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

Файл CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(HelloWorld VERSION 1.0 LANGUAGES CXX)

add_executable(hello main.cpp)

Сборка проекта

mkdir build
cd build
cmake ..
cmake --build .
./hello

Пояснение:

  • cmake_minimum_required — задает минимальную версию CMake.
  • project — определяет имя проекта и язык (CXX для C++).
  • add_executable — создает исполняемый файл из исходников.

Основные методы и функции CMake

1. cmake_minimum_required()

Описание: Устанавливает минимальную версию CMake, необходимую для сборки проекта. Если версия CMake ниже указанной, будет выдана ошибка.

Параметры:

  • VERSION — версия в формате major.minor[.patch[.tweak]]
  • FATAL_ERROR — опционально, вызывает фатальную ошибку при несоответствии версии

Пример:

cmake_minimum_required(VERSION 3.16 FATAL_ERROR)

2. project()

Описание: Определяет имя проекта и его параметры. Должен быть вызван после cmake_minimum_required().

Параметры:

  • projectName — имя проекта
  • VERSION — версия проекта
  • DESCRIPTION — описание проекта
  • LANGUAGES — языки программирования (C, CXX, Fortran и др.)

Пример:

project(MyApp
    VERSION 2.1.0
    DESCRIPTION "Мое приложение на C++"
    LANGUAGES CXX
)

3. add_executable()

Описание: Создает исполняемый файл из указанных исходных файлов.

Параметры:

  • targetName — имя целевого исполняемого файла
  • source1 source2 ... — список исходных файлов (можно использовать переменные)

Пример:

set(SOURCES main.cpp utils.cpp logger.cpp)
add_executable(my_app ${SOURCES})

4. add_library()

Описание: Создает библиотеку (статическую или динамическую) из исходных файлов.

Параметры:

  • targetName — имя библиотеки
  • SHARED | STATIC | MODULE — тип библиотеки
  • source1 source2 ... — исходные файлы

Пример:

add_library(math_lib STATIC math.cpp)
add_library(shared_math SHARED math.cpp)

5. target_link_libraries()

Описание: Связывает целевой объект (исполняемый файл или библиотеку) с другими библиотеками.

Параметры:

  • target — имя целевого объекта
  • PRIVATE | PUBLIC | INTERFACE — спецификатор видимости
  • lib1 lib2 ... — библиотеки для связывания

Пример:

target_link_libraries(my_app PRIVATE math_lib pthread)

6. target_include_directories()

Описание: Добавляет пути поиска заголовочных файлов для целевого объекта.

Параметры:

  • target — имя целевого объекта
  • PRIVATE | PUBLIC | INTERFACE — спецификатор видимости
  • dir1 dir2 ... — директории с заголовочными файлами

Пример:

target_include_directories(my_app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)

7. find_package()

Описание: Ищет и подключает внешние пакеты (библиотеки). Использует модули Find*.cmake или конфигурационные файлы пакетов.

Параметры:

  • packageName — имя пакета
  • version — требуемая версия (опционально)
  • REQUIRED — обязательный пакет (ошибка, если не найден)
  • COMPONENTS — компоненты пакета

Пример:

find_package(Boost 1.75 REQUIRED COMPONENTS filesystem system)
target_link_libraries(my_app PRIVATE Boost::filesystem Boost::system)

8. set()

Описание: Устанавливает значение переменной CMake. Используется для хранения путей, флагов компиляции, списков файлов.

Параметры:

  • variableName — имя переменной
  • value — значение (может быть списком)
  • CACHE — опционально, создает кэшированную переменную

Пример:

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(SOURCES main.cpp utils.cpp)
set(MY_VAR "Hello" CACHE STRING "Описание переменной")

9. option()

Описание: Создает булеву опцию (ON/OFF) для настройки сборки. Пользователь может изменить её через cmake -DOPTION_NAME=ON.

Параметры:

  • optionName — имя опции
  • description — описание опции
  • initialValue — начальное значение (ON или OFF)

Пример:

option(BUILD_TESTS "Собирать тесты" ON)
if(BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()

10. add_subdirectory()

Описание: Добавляет поддиректорию для сборки. В поддиректории должен быть свой CMakeLists.txt.

Параметры:

  • sourceDir — путь к поддиректории
  • binaryDir — опционально, путь для выходных файлов поддиректории
  • EXCLUDE_FROM_ALL — исключить из сборки по умолчанию

Пример:

add_subdirectory(src)
add_subdirectory(libs/mylib EXCLUDE_FROM_ALL)

11. file()

Описание: Выполняет операции с файлами: чтение, запись, поиск, копирование. Очень мощная команда.

Параметры: Зависят от подкоманды (GLOB, COPY, READ, WRITE и др.)

Пример:

file(GLOB_RECURSE SOURCES "src/*.cpp")
file(COPY "config.json" DESTINATION "${CMAKE_BINARY_DIR}")

12. install()

Описание: Определяет правила установки собранных файлов (бинарники, библиотеки, заголовки) в систему.

Параметры:

  • TARGETS — цели для установки
  • DESTINATION — путь установки
  • FILES | DIRECTORY — файлы или директории

Пример:

install(TARGETS my_app DESTINATION bin)
install(FILES config.json DESTINATION etc/my_app)
install(DIRECTORY include/ DESTINATION include)

Реальный практический пример

Создадим полноценный проект: консольное приложение для работы с математическими операциями, использующее внешнюю библиотеку (например, nlohmann/json для JSON).

Структура проекта

math_app/
├── CMakeLists                    

Рекомендаций