Sandbox/CMake: различия между версиями
(Новая страница: «== Что такое CMake? == == == == Как собирать пакеты при помощи CMake == Пример 1 (простой). Вот фрагмен…») |
(видимо, главы будут именно такими...) |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 4: | Строка 4: | ||
== Как собирать пакеты при помощи CMake == | == Как собирать пакеты при помощи CMake == | ||
=== Жизненный цикл пакета: стадия <tt>configure</tt> === | |||
Пример 1 (простой). | Пример 1 (простой). | ||
Вот фрагмент спека: | Вот фрагмент спека: | ||
Строка 49: | Строка 50: | ||
%cmake_build | %cmake_build | ||
</source> | </source> | ||
=== Что писать в <tt>-D $args</tt>? === | |||
* Если проект включает в себя библиотеку для внешнего пользования — скорее всего, её стоит собрать как разделяемую; для этого стоит передать <tt>-DBUILD_SHARED_LIBS:BOOL=ON</tt>. | |||
* Переменная <tt>CMAKE_BUILD_TYPE</tt> управляет т. н. "типом сборки", предусматривающим разное поведение (доп. флаги компиляции/линковки, ) для разных целей. Для генераторов <tt>Ninja</tt> и <tt>Unix Makefiles</tt>, применяемых на Linux, он может быть только один для конкретного каталога артефактов. Например, <tt>Debug</tt>, <tt>Release</tt>, <tt>MinSizeRel</tt>... В большинстве случаев рекомендуется передавать <tt>-DCMAKE_BUILD_TYPE=RelWithDebInfo</tt>. | |||
* Проект, скорее всего, задаёт некоторые собственные флаги, от которых зависят сборочные действия. Их полный список можно увидеть, запустив <tt>cmake -LH</tt> в сборочном окружении. | |||
=== Жизненный цикл пакета: стадия <tt>build</tt> === | |||
=== Жизненный цикл пакета: стадия <tt>install</tt> === | |||
== О подводных и плавучих камнях == | |||
'''Q: <tt>verify-elf: ERROR: ./usr/lib/*: RPATH contains illegal entry "/usr/src/RPM/BUILD": ...</tt>''' | |||
A: CMake [https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling#default-rpath-settings по умолчанию собирает] исполняшки и разделяемые библиотеки с {{term|DT_RUNPATH}}, к которому слева дописаны подкаталоги из каталога сборочных артефактов, чтобы их можно было запускать прямо оттуда и ожидать, что при динамическом связывании подхватятся свежесобранные объекты. На этапе установки собранного в префикс ({{cmd|cmake --install}}) ''этот runpath становится больше не нужен и вымарывается из бинарника''. | |||
Если бинарники ставить не при помощи {{cmd|cmake --install}}, а руками ({{prg|cp(1)}}, {{prg|install(1)}}...), то этого шага не происходит. | |||
Чаще всего ставить бинарники руками просто не нужно, но иногда (например, когда апстрим не указал CMake, что результат некоей цели нужно [https://cmake.org/cmake/help/v3.19/command/install.html установить в билдрут]) приходится. Лучше всего [http://git.altlinux.org/people/arseny/packages/rocksdb.git?p=rocksdb.git;a=commitdiff;h=61e22bdb8fa8fd61d2536b353f5a1036e2fadafd;hp=dbee710c53dc3b02c57e55e6bcf3fa6c39b9c790 исправить cmake-файлы]; если же это слишком сложно, можно просто на configure-этапе передать CMake <tt>-DCMAKE_SKIP_RPATH:BOOL=ON</tt>. | |||
== Ссылки == | == Ссылки == | ||
* [https://cmake.org cmake.org] | * [https://cmake.org cmake.org] | ||
* [https://cmake.org/cmake/help/latest/index.html Официальная документация] | * [https://cmake.org/cmake/help/latest/index.html Официальная документация] | ||
* [https://cliutils.gitlab.io/modern-cmake/ Introduction to Modern CMake] |
Текущая версия от 16:29, 1 июня 2021
Что такое CMake?
Как собирать пакеты при помощи CMake
Жизненный цикл пакета: стадия configure
Пример 1 (простой). Вот фрагмент спека:
%build
%cmake \
$args \
#
%cmake_build
%install
%cmake_install
Он эквивалентен следующему фрагменту:
%build
cmake -S . -B %_target_platform \
$args \
#
cmake --build %_target_platform -j%__nprocs --verbose
%install
DESTDIR=%buildroot cmake --install %_target_platform --verbose
$args могут включать в себя опции конфигурационного шага: -DX=Y, -G $generator, ...
Иногда cmake-проект описывает несколько сборочных целей, и можно собрать одну или несколько из них:
%cmake_build -t $target
Пример 2 (несколько сборочных конфигураций):
%build
%define _cmake__builddir Build1
%cmake $args1
%cmake_build
%define _cmake__builddir Build2
%cmake $args2
%cmake_build
%define _cmake__builddir Build3
%cmake $args3
%cmake_build
Что писать в -D $args?
- Если проект включает в себя библиотеку для внешнего пользования — скорее всего, её стоит собрать как разделяемую; для этого стоит передать -DBUILD_SHARED_LIBS:BOOL=ON.
- Переменная CMAKE_BUILD_TYPE управляет т. н. "типом сборки", предусматривающим разное поведение (доп. флаги компиляции/линковки, ) для разных целей. Для генераторов Ninja и Unix Makefiles, применяемых на Linux, он может быть только один для конкретного каталога артефактов. Например, Debug, Release, MinSizeRel... В большинстве случаев рекомендуется передавать -DCMAKE_BUILD_TYPE=RelWithDebInfo.
- Проект, скорее всего, задаёт некоторые собственные флаги, от которых зависят сборочные действия. Их полный список можно увидеть, запустив cmake -LH в сборочном окружении.
Жизненный цикл пакета: стадия build
Жизненный цикл пакета: стадия install
О подводных и плавучих камнях
Q: verify-elf: ERROR: ./usr/lib/*: RPATH contains illegal entry "/usr/src/RPM/BUILD": ...
A: CMake по умолчанию собирает исполняшки и разделяемые библиотеки с DT_RUNPATH, к которому слева дописаны подкаталоги из каталога сборочных артефактов, чтобы их можно было запускать прямо оттуда и ожидать, что при динамическом связывании подхватятся свежесобранные объекты. На этапе установки собранного в префикс (cmake --install) этот runpath становится больше не нужен и вымарывается из бинарника. Если бинарники ставить не при помощи cmake --install, а руками (cp(1), install(1)...), то этого шага не происходит.
Чаще всего ставить бинарники руками просто не нужно, но иногда (например, когда апстрим не указал CMake, что результат некоей цели нужно установить в билдрут) приходится. Лучше всего исправить cmake-файлы; если же это слишком сложно, можно просто на configure-этапе передать CMake -DCMAKE_SKIP_RPATH:BOOL=ON.