Приложение A. Углублённое пакетирование

Содержание

A.1. Общие библиотеки
A.2. Управление debian/пакет.symbols
A.3. Мультиархитектурность
A.4. Сборка пакета с общей библиотекой
A.5. Родной пакет Debian

Далее приводятся подсказки и ссылки при сложных случаях пакетирования. Настоятельно рекомендуется прочитать все предлагаемые материалы.

Вам может потребоваться вручную отредактировать шаблонные файлы пакета, сгенерированные командой dh_make, чтобы подогнать их под темы, затронутые в этой главе. Новая команда debmake больше подходит к этим темам.

Перед пакетированием общих библиотек прочтите следующие основные документы:

Вот упрощённое представление, для начала:

  • Общие библиотеки — это объектные файлы в формате ELF, в которых содержится скомпилированный код.

  • Общие библиотеки распространяются в виде файлов *.so (не в файлах *.a или *.la).

  • Главным образом, общие библиотеки нужны для совместного использования общего кода в исполняемых файлах посредством механизма ld.

  • Иногда общие библиотеки используются в качестве подключаемых модулей исполняемых файлов посредством механизма dlopen.

  • Общие библиотеки экспортируют символы — скомпилированные объекты: переменные, функции и классы; и разрешают к ним доступ из скомпонованных исполняемых файлов.

  • SONAME общей библиотеки libfoo.so.1: objdump -p libfoo.so.1 | grep SONAME [88]

  • SONAME общей библиотеки обычно совпадает с именем файла библиотеки (но не всегда).

  • SONAME общих библиотек, которые скомпонованы с /usr/bin/foo: objdump -p /usr/bin/foo | grep NEEDED [89]

  • libfoo1: библиотечный пакет общей библиотеки libfoo.so.1 с ABI-версией SONAME, равной 1.[90]

  • Пакетные сценарии сопровождающего для библиотеки должны вызывать ldconfig для создания необходимых символьных ссылок для SONAME при определённых условиях.[91]

  • libfoo1-dbg: пакет с отладочными символами, который содержит символы для отладки пакета с общей библиотекой libfoo1.

  • libfoo-dev: пакет для разработчика, который содержит заголовочные файлы и т .д. общей библиотек libfoo.so.1.[92]

  • Обычно, в пакете Debian не должно быть файлов архива Libtool *.la.[93]

  • Обычно, в пакете Debian не должен использоваться RPATH.[94]

  • Несмотря на некоторое устаревание и статус вторичности, следующая ссылка тоже может быть полезна Debian Library Packaging Guide.

Если пакет содержит общую библиотеку, то вы должны создать файл debian/пакет.symbols, в котором отражена минимальная версия каждого символа обратно совместимых изменений ABI с единым SONAME библиотеки и единым именем пакета с библиотекой.[95] Подробная информация приведена в следующих документах:

Вот примерный план создания пакета libfoo1 для авторской версии 1.3 с подходящим файлом debian/libfoo1.symbols:

  • Подготовьте основу исходного дерева из авторского файла libfoo-1.3.tar.gz.

    • Если пакетирование libfoo1 производится впервые, создайте пустой файл debian/libfoo1.symbols.

    • Если была упакована предыдущая авторская версия 1.2 в пакет libfoo1 с соответствующим файлом debian/libfoo1.symbols в пакете с исходным кодом, то используйте его и сейчас.

    • Если предыдущая авторская версия 1.2 не была упакована с debian/libfoo1.symbols, создайте его как файл symbols из всех доступных двоичных пакетов с единым именем пакета общей библиотеки, содержащих одинаковый SONAME библиотеки, например версии 1.1-1 и 1.2-1. [97]

      $ dpkg-deb -x libfoo1_1.1-1.deb libfoo1_1.1-1
      $ dpkg-deb -x libfoo1_1.2-1.deb libfoo1_1.2-1
      $ : > symbols
      $ dpkg-gensymbols -v1.1 -plibfoo1 -Plibfoo1_1.1-1 -Osymbols
      $ dpkg-gensymbols -v1.2 -plibfoo1 -Plibfoo1_1.2-1 -Osymbols
      
  • Попробуйте выполнить сборку в исходном дереве с помощью таких инструментов как debuild и pdebuild (если возникли ошибки из-за отсутствующих символов и т. д., то это указывает на обратно несовместимые изменения ABI, для которых требуется изменить имя пакета общей библиотеки на что-нибудь вроде libfoo1a и повторить сборку).

    $ cd libfoo-1.3
    $ debuild
    ...
    dpkg-gensymbols: warning: some new symbols appeared in the symbols file: ...
     see diff output below
    --- debian/libfoo1.symbols (libfoo1_1.3-1_amd64)
    +++ dpkg-gensymbolsFE5gzx        2012-11-11 02:24:53.609667389 +0900
    @@ -127,6 +127,7 @@
      foo_get_name@Base 1.1
      foo_get_longname@Base 1.2
      foo_get_type@Base 1.1
    + foo_get_longtype@Base 1.3-1
      foo_get_symbol@Base 1.1
      foo_get_rank@Base 1.1
      foo_new@Base 1.1
    ...
    
  • Если вы видите различие, выдаваемое dpkg-gensymbols, как показано выше, то извлеките обновлённый правильный файл symbols из сгенерированного двоичного пакета общей библиотеки. [98]

    $ cd ..
    $ dpkg-deb -R  libfoo1_1.3_amd64.deb libfoo1-tmp
    $ sed -e 's/1\.3-1/1\.3/' libfoo1-tmp/DEBIAN/symbols \
            >libfoo-1.3/debian/libfoo1.symbols
    
  • Соберите выпускаемые пакеты с помощью таких инструментов как debuild и pdebuild.

    $ cd libfoo-1.3
    $ debuild clean
    $ debuild
    ...
    

В дополнение к вышеупомянутым примерам мы должны проверить дальнейшую совместимость ABI и, если понадобится, увеличить версии некоторых символов вручную. [99]

Несмотря на статус вторичности, вики Debian UsingSymbolsFiles и содержащиеся на ней ссылки могут быть полезными.

Свойство мультиархитектурности, появившееся в Debian wheezy, встраивает поддержку кросс-платформенной установки двоичных пакетов (а именно i386<->amd64, но есть и другие комбинации) в dpkg и apt. Подробная информация приведена в следующих документах:

При установке общих библиотек в путях используются триплеты, например i386-linux-gnu и x86_64-linux-gnu. Актуальный триплет динамически задаётся в переменной $(DEB_HOST_MULTIARCH) с помощью dpkg-architecture(1) при каждой сборке. Например, путь установки мультиархитектурных библиотек изменяется следующим образом:[100]

Вот несколько примеров разделения типично мультиархитектурных пакетов:

  • библиотека с исходным кодом libfoo-1.tar.gz

  • инструмент с исходным кодом bar-1.tar.gz, написанный на компилируемом языке

  • инструмент с исходным кодом baz-1.tar.gz, написанный на интерпретируемом языке

Заметим, что пакет для разработчика должен содержать символьную ссылку на соответствующую общую библиотеку без номера версии. Пример: /usr/lib/x86_64-linux-gnu/libfoo.so -> libfoo.so.1

Вы можете собрать пакет Debian с библиотекой, включающий поддержку мультиархитектурности с помощью команды dh(1):

Проверьте, что пакет с общей библиотекой содержит только ожидаемые файлы и что ваши пакеты -dev ещё работают.

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

Если пакет сопровождается только для Debian или, возможно, предназначен только для локального использования, то файлы debian/* можно хранить прямо его в исходном коде. Есть два способа его пакетирования.

Вы можете использовать авторский tarball, исключив из него файлы debian/* и упаковав его как неродной пакет Debian (Раздел 2.1, «Порядок сборки пакета Debian». Это — обычный способ, которые предпочитают использовать некоторые люди.

Альтернативный способ сборки родного пакета Debian:

  • создание родного пакета Debian с исходным кодом в формате 3.0 (native), состоящем из одного сжатого файла tar, в который включены все файлы

    • пакет_версия.tar.gz
    • пакет_версия.dsc
  • сборка двоичных пакетов Debian из родного пакета Debian с исходным кодом

    • пакет_версия_архитектура.deb

Например, если у вас есть файлы исходного кода в ~/mypackage-1.0 и нет файлов debian/*,то можете создать родной пакет Debian с помощью команды dh_make следующим образом:

$ cd ~/mypackage-1.0
$ dh_make --native

В результате будет создан каталог debian и его содержимое, как в Раздел 2.8, «Начальный неродной пакет Debian». При этом архив tar не создаётся, так как это родной пакет Debian — в этом единственное отличие. Остальные действия по пакетированию практически ни чем не отличаются.

После выполнения команды dpkg-buildpackage, вы увидите следующие файлы в родительском каталоге:

  • mypackage_1.0.tar.gz

    Это сжатый архив tar с исходным кодом, созданный из каталога mypackage-1.0 командой dpkg-source (его суффикс не orig.tar.gz).

  • mypackage_1.0.dsc

    Содержит описание содержимого пакета с исходным кодом, такой же как для неродного пакета Debian (в имени нет редакции Debian).

  • mypackage_1.0_i386.deb

    Собранный двоичный пакет, такой же как для неродного пакета Debian (в имени нет редакции Debian).

  • mypackage_1.0_i386.changes

    Содержит описание всех изменений, сделанных в текущей версии пакета, такой же как для неродного пакета Debian (в имени нет редакции Debian).



[88] Либо: readelf -d libfoo.so.1 | grep SONAME

[89] Либо: readelf -d libfoo.so.1 | grep NEEDED

[95] При обратно несовместимых изменениях ABI обычно требуется обновить SONAME библиотеки и поменять имя пакета общей библиотеки на новое.

[96] Вместо указанного для библиотек C++ и в других случаях, где слежение за отдельными символами слишком сложно, прочтите руководство по политике Debian, раздел 8.6.4 «Система shlibs».

[97] Все предыдущие версии пакетов Debian доступны по http://snapshot.debian.org/. Для облегчения переноса пакета в старые выпуски часть, отвечающая за версию Debian, отбрасывается: 1.1 << 1.1-1~bpo70+1 << 1.1-1 и 1.2 << 1.2-1~bpo70+1 << 1.2-1

[98] Для облегчения переноса пакета в старые выпуски часть, отвечающая за версию Debian, отбрасывается: 1.3 << 1.3-1~bpo70+1 << 1.3-1

[100] Старые пути к библиотекам, служащие для этих целей, такие как /lib32/ и /lib64/, больше не используются.

[101] Или же вы можете добавить параметры --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) и --libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) в ./configure. Заметим, что в --libexecdir задаётся путь по умолчанию для установки исполняемых программ, запускаемых другими программами, а не пользователями. Значение Autotools по умолчанию равно /usr/libexec/, но значение Debian по умолчанию равно /usr/lib/.