Есть ли способ автоматически определять зависимости при настройке управляющего файла dpkg?

Большинство полей в управляющем файле dpkg (Debian) просты. Сложность заключается в определении списка зависимостей (Depends:). Я надеялся, что dpkg-gencontrol сможет сделать это за меня, просмотрев вывод ldd для исполняемых файлов в каталоге пакета. Возможно, он может, но я не могу заставить его работать.

Если это то, для чего предназначен dpkg-gencontrol, я получаю сообщение об ошибке:

dpkg-gencontrol: error: syntax error in control_template at line 7: first block lacks a source field.

Для справки, команда dpkg-gencontrol -v1.1 -ccontrol_template -lchangelog -Pdebian. Файл control_template содержит следующее:

Package: my-package
Maintainer: Joe Coder <[email protected]>
Description: The my-package system
 A longer description that runs to the end of one line and then 
 extends to another line.
Priority: optional

Если это не то, для чего предназначен dpkg-gencontrol, есть ли у кого-нибудь предложения относительно того, что я могу сделать, или советы о том, как настроить список зависимостей, в идеале автоматически?

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

Обратите внимание, что это только для внутреннего распространения. Я не собираю пакет для использования в дистрибутиве Linux или даже для широкой публики, поэтому я буду рад изменить/нарушить стандартные правила, если это необходимо.


person Randall Cook    schedule 04.11.2011    source источник


Ответы (2)


После некоторого копания, вдохновленного ответом Титона, и множества проб и ошибок, я наконец нашел решение своей проблемы. Оказывается, dpkg-gencontrol — это не инструмент для определения зависимостей пакетов от исполняемых файлов, а dpkg-shlibdeps. Однако необходимо тщательно настроить все, чтобы две программы помогли сгенерировать пакет. Читать дальше....

Запуск dpkg-shlibdeps -O <executable> приводит к отображению списка пакетов и версий, которые необходимо установить для запуска этого исполняемого файла. Идеально. Почти. В идеале dpkg-gencontrol мог бы использовать это в своей обработке, которую, как утверждается, он может делать с помощью своей функции подстановки переменных.

Чтобы все прошло гладко, мне пришлось создать структуру каталогов, соответствующую ожиданиям инструментов упаковки Debian. В основном это выглядит так:

my_project_directory/
  main.c (or other source code, etc.)
  debian/
    changelog    (created by hand; see below)
    control      (this is basically a template, created by hand; see below)
    files        (created by dpkg-gencontrol)
    substvars    (created by dpkg-shlibdeps and used by dpkg-gencontrol)
    tmp/         (tmp is the root of the target system's filesystem)
      path/
        to/
          my/
            project/
              executable_1  (this will be installed at /path/to/my/project)
              executable_2  (this, too)
      var/
        www/
          index.php  (this will be installed at /var/www on target systems)
      DEBIAN/        (create this by hand)
        control      (created by dpkg-gencontrol and used in the final package)

Обратите внимание, что инструменты упаковки Debian сохраняют владельца и группу всех файлов в каталоге debian/tmp/. Таким образом, если вы хотите, чтобы при установке файлы принадлежали root или другому пользователю, все становится сложнее. Один из вариантов — подготовить дерево каталогов debian как root и установить владельцев по своему усмотрению. Если вы предпочитаете не работать с правами root или вам это не разрешено, есть другой способ.

Создайте скрипт, который вызывает chown и т. д., чтобы настроить владельцев по своему усмотрению, с последней строкой dpkg-deb -b debian/tmp . (которая создает пакет .deb, см. пример ниже). Запустите его через fakeroot, еще один инструмент Debian, вот так: fakeroot ./fix_ownerships_and_build.sh. Fakeroot позволяет программам вести себя так, как если бы они были root, без фактического изменения вещей, как это сделал бы root. Он был создан именно для этого сценария.

Я изучил, почему dpkg-gencontrol генерировал ошибку «в первом блоке отсутствует исходное поле», даже заходя так далеко, что читал исходный код Perl. Как это часто бывает, код ошибки точен, но не содержит достаточного контекста, чтобы знать, что делать: управляющему файлу действительно нужно поле с именем «источник» в его первом (из двух) блоке.

Существует два вида пакетов Debian: исходный код и двоичный файл. Я думал, что мне нужен двоичный файл, так как я просто хочу поместить в него скомпилированные исполняемые файлы, но я не мог заставить его работать. Я попробовал исходный пакет и добавил исходное поле в свой управляющий файл. Это избавило от ошибки «в первом блоке отсутствует исходное поле», но привело к другой. Изучив документацию более внимательно, я понял, что пакетам с исходным кодом нужны два "абзаца" в своих управляющих файлах. Как только я изменил свой управляющий файл, чтобы он выглядел так, он начал работать (почти):

Source: my-package
Maintainer: Joe Coder <[email protected]>

Package: my-package
Priority: optional
Architecture: amd64
Depends: ${shlibs:Depends}, apache2, php5
Description: The My-Package System
 A longer description that runs to the end of one line and then
 extends to another line.

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

my-package (1.0) unstable; urgency=low
  * placeholder changelog to satisfy dpkg-gencontrol
 -- Joe Coder <[email protected]>  Thu, 3 Nov 2011 16:49:00 -0700

Два начальных пробела в строке со знаком * необходимы, как и один начальный пробел в строке с --, а также два пробела между адресом электронной почты и датой. И да, дата должна быть такой точной, часовой пояс и все такое, даже если она не обязательно должна быть точной.

Собрав все вместе, с деревом каталогов Debian, настроенным, как описано выше, последовательность команд, необходимых для сборки пакета, выглядит следующим образом:

dpkg-shlibdeps debian/tmp/path/to/my/project/executable_1 \
               debian/tmp/path/to/my/project/executable_2
dpkg-gencontrol -v1.1  (or whatever version you are building)
fakeroot ./fix_ownerships_and_build.sh

где fix_ownersships_and_build.sh выглядит так:

chown -R root:root debian/tmp/path  (or whatever user is appropriate)
chown -R www-data:www-data debian/tmp/var/www/*  (same goes here)
dpkg-deb -b debian/tmp .  (this leads to a nice my-package_1.1_amd64.deb file)

Итак, это все. Надеюсь, этот ответ поможет другим добиться прогресса быстрее, чем я.

person Randall Cook    schedule 10.11.2011
comment
Хорошая работа, но вы перепрограммировали большую часть dpkg-buildpackage. Вы знаете об этом инструменте, не так ли? - person thiton; 13.11.2011
comment
В некотором роде. Существуют десятки инструментов, связанных с dpkg, и я хотел, чтобы все было просто. Инструменты Debian также казались слишком сосредоточенными на создании пакетов из основных источников для распространения вместе с самим Debian, что не совсем то, что я пытался сделать. Я начал с построения простого дерева каталогов, минимального управляющего файла и единственного вызова dpkg-deb -b. Я пытался найти минимальные дополнения к этой базе, чтобы получить то, что я хотел. Типа выросло. :) Я посмотрю dpkg-buildpackage. Изобретение колеса часто является важной частью обучения. - person Randall Cook; 13.11.2011

На самом деле просмотр списка включенных библиотек — обычное дело для программ на C и это просто работа хелпера shlibs (dpkg-shlibdeps). Посмотрите на его справочную страницу, но в основном все сводится к использованию ${shlibs:Depends} в строке зависимостей.

person thiton    schedule 06.11.2011
comment
Это была подсказка, которая заставила меня начать поиск решения. Спасибо, Тилтон. И для справки, помог не dh_shlibdeps, а dpkg-shlibdeps. - person Randall Cook; 10.11.2011