05 марта 2026 № 1 (2026)

ROSARIUM

газета советского программиста

CMake

Современная кроссплатформенная система сборки.

На этой странице

CMake — популярная кроссплатформенная система сборки. Генерирует Makefile (или Ninja) из описания CMakeLists.txt.

Признаки CMake

В исходниках есть:

  • CMakeLists.txt в корне
  • Возможно, каталог cmake/ с модулями

Стандартная сборка

%build
%cmake
%cmake_build

%install
%cmake_install

Макросы подробно

%cmake

%cmake [опции]

Раскрывается примерно в:

mkdir -p redhat-linux-build
cd redhat-linux-build
cmake .. \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_BUILD_TYPE=RelWithDebInfo \
    -DCMAKE_C_FLAGS="%{optflags}" \
    -DCMAKE_CXX_FLAGS="%{optflags}" \
    -DCMAKE_INSTALL_LIBDIR=/usr/lib64 \
    -DCMAKE_INSTALL_INCLUDEDIR=/usr/include \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    [ваши опции]

С опциями:

%cmake \
    -DENABLE_TESTS=ON \
    -DWITH_GTK4=ON \
    -DBUILD_SHARED_LIBS=ON

%cmake_build

%cmake_build [цели]

Собирает проект в каталоге сборки.

%cmake_install

%cmake_install

Устанавливает в buildroot.

Полный пример SPEC

Name:           myproject
Version:        1.0.0
Release:        1%{?dist}
Summary:        My CMake project
License:        MIT
URL:            https://github.com/user/myproject
Source0:        %{url}/archive/v%{version}/%{name}-%{version}.tar.gz

BuildRequires:  cmake >= 3.16
BuildRequires:  gcc-c++
BuildRequires:  ninja-build
BuildRequires:  pkgconfig(Qt6Core)
BuildRequires:  pkgconfig(Qt6Widgets)

%description
My project built with CMake.

%package devel
Summary:        Development files for %{name}
Requires:       %{name}%{?_isa} = %{version}-%{release}

%description devel
Development files for %{name}.

%prep
%autosetup

%build
%cmake -GNinja
%cmake_build

%install
%cmake_install

%check
%ctest

%files
%license LICENSE
%doc README.md
%{_bindir}/myapp
%{_libdir}/libmylib.so.1*

%files devel
%{_includedir}/mylib/
%{_libdir}/libmylib.so
%{_libdir}/cmake/mylib/
%{_libdir}/pkgconfig/mylib.pc

%changelog
* Mon Feb 03 2025 Your Name <your@email.com> - 1.0.0-1
- Initial package

Использование Ninja

Ninja быстрее Make для больших проектов:

BuildRequires:  ninja-build

%build
%cmake -GNinja
%cmake_build

%install
%cmake_install

Типичные опции CMake

Типы сборки

%cmake -DCMAKE_BUILD_TYPE=Release
# Или для отладки
%cmake -DCMAKE_BUILD_TYPE=Debug

RPM по умолчанию использует RelWithDebInfo (оптимизация + отладочные символы).

Включение/отключение возможностей

%cmake \
    -DENABLE_TESTS=ON \
    -DENABLE_DOCS=OFF \
    -DWITH_SYSTEMD=ON \
    -DBUILD_SHARED_LIBS=ON

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

%cmake \
    -DCMAKE_INSTALL_SYSCONFDIR=%{_sysconfdir} \
    -DCMAKE_INSTALL_LOCALSTATEDIR=%{_localstatedir}

Использование системных библиотек

%cmake \
    -DUSE_SYSTEM_ZLIB=ON \
    -DUSE_BUNDLED_SQLITE=OFF

Тестирование

Макрос %ctest

%check
%ctest

Раскрывается в:

cd redhat-linux-build
ctest --output-on-failure

С дополнительными опциями

%check
%ctest --timeout 300

Пропуск определённых тестов

%check
%ctest --exclude-regex "slow_test|flaky_test"

Отладка CMake

Посмотреть доступные опции

cd ~/rpmbuild/BUILD/project-1.0
cmake -LH .
# Или интерактивно
ccmake .

Посмотреть, что определено

cat CMakeCache.txt | grep -v "^#" | grep -v "^$"

Verbose-сборка

%build
%cmake
%cmake_build -- VERBOSE=1

Out-of-source сборка

RPM-макросы автоматически создают отдельный каталог сборки:

BUILD/project-1.0/
├── CMakeLists.txt
├── src/
└── redhat-linux-build/    ← Каталог сборки
    ├── CMakeCache.txt
    └── Makefile

Особые случаи

In-source сборка (если требуется)

%build
%cmake -B .
%cmake_build

%install
%cmake_install -B .

Несколько конфигураций

%build
# Release
%cmake -B build-release -DCMAKE_BUILD_TYPE=Release
%cmake_build -B build-release

# Debug (если нужно)
%cmake -B build-debug -DCMAKE_BUILD_TYPE=Debug
%cmake_build -B build-debug

CMake presets

Если проект использует CMakePresets.json:

%build
cmake --preset release
cmake --build --preset release

%install
DESTDIR=%{buildroot} cmake --install build/release

Типичные проблемы

«Could not find package X»

CMake Error: Could not find a package configuration file provided by "X"

Найти и добавить BuildRequires:

dnf provides '*/XConfig.cmake'
dnf provides 'cmake(X)'

«Imported target not found»

Библиотека установлена, но CMake её не видит. Возможно, нужен -devel пакет:

dnf provides 'cmake(Qt6Core)'
# qt6-qtbase-devel

Конфликт версий CMake

BuildRequires:  cmake >= 3.16

Неправильный путь библиотек

%cmake -DCMAKE_INSTALL_LIBDIR=%{_libdir}

Полезные переменные CMake

ПеременнаяНазначение
CMAKE_INSTALL_PREFIXПрефикс установки (/usr)
CMAKE_BUILD_TYPEТип сборки (Release, Debug, …)
CMAKE_INSTALL_LIBDIRКаталог библиотек (lib64)
BUILD_SHARED_LIBSСобирать разделяемые библиотеки
CMAKE_VERBOSE_MAKEFILEПодробный вывод

Проверьте понимание

  1. Какой файл указывает на использование CMake?
  2. Что делает опция -GNinja?
  3. Как запустить тесты CMake-проекта?
  4. Как узнать, какие опции поддерживает проект?
  5. Как включить опцию ENABLE_FEATURE?

Далее: Meson