Упаковка компонентов CMake для Debian

Вопрос или проблема

У меня есть один исходный пакет верхнего уровня, использующий cmake, и я хотел бы упаковать его как два двоичных пакета Debian.

$ tree proj
proj/
├── app1.c
├── app2.c
└── CMakeLists.txt

Исходный CMakeLists.txt уже написан с учетом этого. Они используют аргумент COMPONENTS команды install

$ cat proj/CMakeLists.txt
include(GnuInstallDirs)

add_executable(app1 app1.c)
install(
  TARGETS app1 
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  COMPONENT app1)

add_executable(app2 app2.c)
install(
  TARGETS app2
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  COMPONENT app2)

Чтобы собрать/установить локально, это довольно просто:

$ mkdir build && cd build
$ cmake ../proj -DCMAKE_INSTALL_PREFIX=/usr/local  # Настройка
$ cmake --build .                                  # Сборка
$ cmake -DCOMPONENT=app1 -P cmake_install.cmake    # Установить компонент app1
$ cmake -DCOMPONENT=app2 -P cmake_install.cmake    # Установить компонент app2

Но как бы вы создали файл debian/rules для этого?

Стандартный файл debhelper debain/rules может выглядеть так (система сборки автоматически распознает cmake на более новых уровнях совместимости).

%:
        dh $@    # --buildsystem=cmake  <-- более старые уровни совместимости могут нуждаться в этом

Это эффективно запустит make install DESTDIR=debian/tmp. Но это помещает все в одно место назначения, заставляя вас вручную писать файлы debian/*.install, чтобы разделить его на части (см. dh_install(1)). Это обычный способ превращения монолитного исходника cmake в несколько двоичных файлов, и есть хорошее руководство по этому вопросу в руководстве Debian здесь.

Однако, верхний уровень уже сделал эту работу, определив установки COMPONENT.

Чтобы воспользоваться этим, переопределите свой собственный рецепт установки, чтобы указать ассоциацию пакета/компонента:

include /usr/share/dpkg/architecture.mk

%:
        dh $@

override_dh_auto_install:
        sed -i -е 's/\-P/\-DCOMPONENT\=app1\ \-P/g' obj-$(DEB_HOST_MULTIARCH)/Makefile
        dh_auto_install --destdir=debian/app1

        sed -i -е 's/\-DCOMPONENT\=app1/\-DCOMPONENT\=app2/g' obj-$(DEB_HOST_MULTIARCH)/Makefile
        dh_auto_install --destdir=debian/app2

Корень debian/<binary_package_name> представляет / в этом двоичном пакете.

Я немного разочарован командами sed. Я надеялся сделать это, передавая -- -DCOMPONENT=app1 в каталог dh_auto_install. Вместо этого эти команды редактируют файл Makefile, сгенерированный cmake. Это решение предполагает, что вы используете make, и что единственная строка -P будет в ваших командах установки (что, похоже, имеет место для проектов, которые я проверял до сих пор). Я рад принять правки к этому ответу с лучшим решением.

Примечание: компания Kitware (разработчик cmake) работает над новым расширением debhelper dh-cmake, которое, по-видимому, упростит это. Однако, на момент выпуска Debian 10 (buster) оно еще недоступно.

Спустя годы я вернулся к этому с лучшим ответом: dh-cmake сейчас доступен и работает хорошо. Установите пакет Debian dh-cmake.

В приведенном выше примере я добавил dh-cmake, dh-cmake-compat (= 1) и dh-sequence-cmake в качестве зависимостей для сборки. Этого достаточно, чтобы задействовать dh-cmake в процессе сборки.

debian/control:

Source: proj
Maintainer: Stewart <[email protected]>
Build-Depends:
 debhelper-compat (= 13),
 dh-cmake,
 dh-cmake-compat (= 1),
 dh-sequence-cmake

Package: proj-app1
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}

Package: proj-app2
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}

Далее нам нужно сопоставить компоненты cmake с пакетами. Сделайте это, перечислив каждый компонент в соответствующем <package>.cmake-components.

debian/proj-app1.cmake-components:

app1

debian/proj-app2.cmake-components:

app2

Нет необходимости поддерживать debian/<package>.install, переопределять что-либо в debian/rules или изменять CMakeLists.txt верхнего уровня. debian/rules может оставаться таким же простым:

#!/usr/bin/make -f

%:
        dh $@

Ответ или решение

Вопрос о том, как упаковать CMake компоненты в Debian, является актуальной темой для многих разработчиков, стремящихся оптимизировать свою работу с пакетами. Основной задачей является создание двух бинарных пакетов Debian из одного источника CMake, где в исходниках уже использованы аргументы COMPONENTS для установки.

Предпосылки

Ваша проектная структура и CMakeLists.txt настроены так, чтобы компоненты могли устанавливаться отдельно:

proj/
├── app1.c
├── app2.c
└── CMakeLists.txt

CMakeLists.txt содержит установки, разделенные по компонентам "app1" и "app2":

add_executable(app1 app1.c)
install(
  TARGETS app1 
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  COMPONENT app1)

add_executable(app2 app2.c)
install(
  TARGETS app2
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  COMPONENT app2)

Создание файла debian/rules

Стандартный файл debian/rules для debhelper может выглядеть следующим образом:

%:
    dh $@

Тем не менее, для работы с установленными COMPONENTS, потребуется специфический подход для ассоциации компонентов с пакетами. Используйте следующие шаги для этого:

  1. Использование dh-cmake: Убедитесь, что у вас установлены dh-cmake, dh-cmake-compat (= 1) и dh-sequence-cmake. Эти инструменты помогут в процессе создания пакетов.

  2. Правка debian/control:

    Source: proj
    Maintainer: Ваше Имя <[email protected]>
    Build-Depends:
    debhelper-compat (= 13),
    dh-cmake,
    dh-cmake-compat (= 1),
    dh-sequence-cmake
    
    Package: proj-app1
    Architecture: any
    Depends: ${shlibs:Depends}, ${misc:Depends}
    
    Package: proj-app2
    Architecture: any
    Depends: ${shlibs:Depends}, ${misc:Depends}
  3. Создание файлов для компонентов: Ассоциируйте компоненты с пакетами, создав соответствующие файлы:

    • debian/proj-app1.cmake-components содержит:

      app1
    • debian/proj-app2.cmake-components содержит:

      app2

Заключение

С внедрением dh-cmake, процесс разделения компонентов CMake на разные пакеты становится автоматизированным и удобным. Ваша структура debian/rules может оставаться минималистичной, поскольку большая часть механики обрабатывается за вас.

Подход, описанный выше, позволяет эффективно управлять процессом упаковки, сокращая ручную работу и минимизируя вероятность ошибок. Мы рекомендуем регулярно проверять новые возможности и обновления в инструментах упаковки Debian для поддержания вашего процесса на современном уровне.

Оцените материал
Добавить комментарий

Капча загружается...