Введение в 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
- Скачайте установщик с официального сайта (выберите версию для Windows — .msi или .zip).
- Запустите установку. Обязательно отметьте опцию "Add CMake to the system PATH for all users".
- После установки проверьте:
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