10/14/2013

Репозиторий deb-пакетов своими руками: сборка пакетов в Debian из исходников и бинарников на скорую руку

Часто бывает нужно по-быстрому собрать deb-пакет в Debian, особенно когда уже имеется бинарный файл. Так как мы не слакварщики и не хотим засорять систему make & make install, мы пойдём другим путём и сделаем собственный пакет. А чтобы они не валялись по всему диску, закатаем наши пакеты в собственный же репозиторий.

Распаковка существующих пакетов

Сначала посмотрим, что внутри пакета deb или rpm.

Распаковка deb-пакета

Распаковать пакет Debian нужно в два этапа - сначала извлекаем из него файлы, а потом добираемся до собственно бинарников. Вскрываем пакетик:
# ar vx mypackage.deb
Файл пакета mypackage.deb содержит три вложенных файла:
  • debian-binary - это текстовый файл, который содержит информацию о версии пакета (например: 2.0)
  • control.tar.gz - этот архив содержит всю мета-информацию: имя и версию пакета, зависимости и прочее.
  • data.tar.gz - собственно, бинарники программы, необходимые для работы. Именно эти файлы будут разархивированы в каталог /usr для дальнейшего использования.
Теперь, если нам охота поживиться бинарниками пакета (содержимое data.tar.gz), даём команду:
$ tar -xzvf data.tar.gz
В текущем каталоге появится ./usr текущего каталога. Желанный бинарник лежит в ./usr/bin подкаталоге.

Если же вам нужно просто извлечь файлы из пакета, можно всё сделать одной командой
$ ar p mypackage.deb data.tar.gz | tar zx
это распакует пакет deb в текущий каталог. Другой вариант - использовать dpkg-deb в виде:
$ dpkg-deb -x что.deb куда/


Распаковка rpm-пакета

На всякий случай о том, как распаковать пакеты вероятного противника RPM-based систем. Для этого нам потребуются программы rpm2cpio и cpio. Распаковка содержимого RPM пакета делается в один шаг:
$ rpm2cpio mypackage.rpm | cpio -vid
Если же нужно просмотреть содержимое пакета, не распаковывая его, даём команду:
$ rpm2cpio mypackage.rpm | cpio -vt
Для того, чтобы (попытаться) конвертировать RPM-пакет в Debian, можно воспользоваться командой:
# alien mypack.i386.rpm
Надо сказать, что пакеты RPM и DEB сильно отличаются друг и друга, и такое простое конвертирование не всегда проходит.

Deb-пакет из бинарного файла

Теперь, когда мы знаем, что ничего волшебного внутри deb-пакетов нет, можно попробовать сварганить свой собственный дебиановский пакетик.
Часто хочется сделать побыстрее, чтоб "завелось и поехало" - и вместо пакетов пользователи устанавливают программы в виде ./configure, make & make install (вместо make install можно использовать checkinstall). Как уже говорилось не раз, не стоит поддаваться искушению и ставить программы в Linux в обход менеджера пакетов - пакетный менеджер ничего о них знать не будет, и при обновлении системы вы рискуете получить больше проблем на свою голову, чем представляете.
Иногда бывает так, что исходников к пакету нет - скажем, поступила к нам проприетарщина, а упаковать её в пакет хочется. Или мы наваяли скрипт, и хочется, чтобы он был на многих машинах. Нет проблем: завернём это в deb-пакет и скормим apt-у.
Для этого нам понадобится утилита
# apt-get install dpkg-dev
Подопытным кроликом будет служить бинарный файл системы контроля версий fossil, о котором уже говорилось ранее.
Идея в том, чтобы в локальном каталоге (назовём его ~./tempprog) отдублировать структуру каталогов для программы так, как она лежала бы в системе в установленном виде. Большинство бинарников находится в системном каталоге /usr/bin, поэтому создаём такую же структуру в локальном:
$ mkdir -p ./tempprog/usr/bin/
Так мы создадим все подкаталоги за один проход. Зайдём внутрь:
$ cd tempprog/
и увидим созданные подкаталоги:
$ tree
Вот они:

.
└── usr
     └── bin
2 directories, 0 files

Отлично, теперь в локальном каталоге ./tempprog создаём подкаталог ./DEBIAN:
$ mkdir ./DEBIAN

Внутри подкаталога ./DEBIAN создаём текстовый файл control с таким содержимым:
Package: имя-пакета
Version: версия пакета, скажем 1.0 или 2.7.9.
Architecture: архитектура(i386, amd64, all...)
Maintainer: сопровождающий_пакета
Installed-Size: размер программы в килобайтах
Depends: зависимости (пакет (>= версия))
Recommends: рекомендации (пакет (>= версия))
Suggests: предложения (пакет)
Section: секция (multimedia, games, system, или другое)
Priority: приоритет (optional)
Homepage: http://www.домашняя_страница
Description: описание программы 

Таким образом, в нашем локальном каталоге ./tempprog будет лежать вот что:

.
├── DEBIAN
│.. └── control
└── usr
    └── bin
        └── fossil
3 directories, 2 files

Теперь из каталога ./tempprog даём команду на сборку этого простенького пакета:
$ dpkg-deb -b ./ ./
В результате появится пакет (в нашем примере с fossil) вида:
fossil_1.21_i386.deb
который можно сразу же установить в систему:

$ sudo dpkg -i fossil_1.21_i386.deb
[sudo] password for starscream:
Selecting previously deselected package fossil.
(Reading database ... 247627 files and directories currently installed.)
Unpacking fossil (from fossil_1.21_i386.deb) ...
Setting up fossil (1.21) ...

И всё, наступает счастье.

Небольшое примечание: если кто хочет установить программу в директорию
/opt/ нужно сделать следующее:

- В локальном каталоге ./tempprog создаём каталог /opt/ и размещаем там
программу так, как она и будет установлена в /opt
- Там же, в ./tempprog создаём подкаталоги /tempprog/usr/bin/
в котором размещаем небольшой скрипт, например zotero
- В нём пишем:

#! /bin/sh
PATH=$PATH:/opt/zotero/
/opt/zotero/zotero

Это говорит системе, что теперь можно запускать файлы и из /opt/zotero


Deb-пакет из исходников на скорую руку

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

Если нам повезло и все зависимости уже в системе, можно скомпилировать исходные тексты программы и по-быстрому завернуть всё в пакет Debian.

Для этого скачанные исходные тексты программы (для примера foobar версии 1.2.3) распаковываем в каталог foobar-1.2.3, и от рута даём команду:
# dh_make --createorig
Далее пишем
# debuild
Опять, если нам повезло, всё должно собраться без вопросов. Полученный пакет устанавливаем
# dpkg -i foobar_1.2.3-1_i386.deb
Охочим до тонкостей дебиановской кулинарии и прочим правильно писающим мальчикам просьба пройти сюда и насладиться The Debian Administrator's Handbook. Эта Книга о вкусной и здоровой пище довольно занудная, водянистая и словоохотливая книжеца от двух дебианщиков расскажет вам о Debian Policy, как всё делать ортодоксально и, когда авторы вспоминают, что не мемуары пишут, про то, что же таки собственно делать.

Создание собственного локального репозитория Debian своими руками

Когда количество собственноручно собранных пакетов перевалит за десяток, захочется удобства и комфорта установки софта. К счастью, создание собственного локального репозитория - дело сравнительно простое.

Создаём каталог, в котором будут лежать все собранные непосильным трудом пакеты - пусть это будет ~/zips/virensdebianrepositor в который копируем deb-пакеты.

Для создания репозитория нам понадобится dpkg-scanpackages который является (во всяком случае на момент написания поста) частью пакета dpkg-dev, как это неожиданно выяснилось.

Создаём список пакетов:
$ dpkg-scanpackages . /dev/null | gzip -9c > ./Packages.gz
Может быть, нам будет выведено сообщение типа:

dpkg-scanpackages: warning: Packages in archive but missing from override file:
dpkg-scanpackages: warning:   fossil linux-headers-3.8.0-avl9-pae linux-image-3.8.0-avl9-pae pdfsam sublimetext virtualbox-4.2 xserver-xorg-input-wacom zotero
dpkg-scanpackages: info: Wrote 8 entries to output Packages file.

Теперь в нашем репозитории 8 пакетов. Отлично, добавляем наш репозиторий в файл:
# vim /etc/apt/sources.list
строчкой типа:

deb file:///home/имя_пользователя/zips/virensdebianrepository ./

Теперь нужно обновить список пакетов, чтобы они стали доступны для установки:
# apt-get update
Всё, теперь можно установить, к примеру, свежесобранный текстовый редактор Sublime Text 2 (отличная инструкция там) как всегда: Теперь, для того, чтобы установить SublimeText достаточно сделать:

# apt-get install sublimetext

Reading package lists... Done
 Building dependency tree
 Reading state information... Done
 The following NEW packages will be installed:
   sublimetext
 0 upgraded, 1 newly installed, 0 to remove and 245 not upgraded.
 Need to get 0 B/11.4 MB of archives.
 After this operation, 17.4 MB of additional disk space will be used.
 WARNING: The following packages cannot be authenticated!
   sublimetext
 Install these packages without verification [y/N]? Y
 Selecting previously deselected package sublimetext.
 (Reading database ... 247813 files and directories currently installed.)
 Unpacking sublimetext (from ..././sublimetext_2.0.2_i386.deb) ...
 Setting up sublimetext (2.0.2) ... 
Всё, пакет будет распакован и установлен, а то, что он из местного репозитория, видно вот тут: (from ..././sublimetext_2.0.2_i386.deb)

Заключение

Описанные в этом посте рецепты - блюда на скорую руку, а не фуагра с трюфелями. Для больших репозиториев или сложных пакетов придётся-таки ознакомиться с документацией и руководствами. Ещё можно воспользоваться программой APTonCD, которая умеет не только создавать репозитории, но и записывать их на CD/DVD диски.

17 комментариев:

  1. Очень полезный пост. Для убунты пару раз собирал репозитории, а вот до дебиана руки не доходили. А тут уже подробное руководство :-)

    Кстати, точно помню, что в убунте можно было воспользоваться приблудой под названием APTonCD. Репозиторий делала немножко коряво, но зато позволяла в пару кликов сделать репозиторий из кеша APT. Думаю, что о ней стоит упомянуть

    ОтветитьУдалить
  2. @Vladimir Vlsu комментирует...

    Очень полезный пост.
    Дык, а то! Баянист со стажем, шо ж ты хочешь... :-)

    Для убунты пару раз собирал репозитории, а вот до дебиана руки не доходили.
    А там всё одно и тоже. Кстати, в комментариях рецептиками не поделишься?

    Кстати, точно помню, что в убунте можно было воспользоваться приблудой под названием APTonCD. Репозиторий делала

    Зачем на CD? Мне просто локальный репозиторий сделать, записывать не надо. Но согласен - упомянуть стоит.
    А вообще джедаи идут другим путём... :-)


    Отдельное спасибо тов. brainstream, который указал на баг в посте с отрисовкой окружения PRE. Такое бывает, когда доверяешь хаскельным поделкам вроде pandoc :-)

    Да, если есть что добавить - пишите в комментариях, но учтите, что пост - именно на скорую руку, без нужды перечитывать фолианты Debian Packaging Guidelines и прочую квантовую физику.

    ОтветитьУдалить
  3. Ошибка у вас в тексте:
    "Теперь, для того, чтобы установить Skype достаточно сделать:

    # apt-get install sublimetext "

    ОтветитьУдалить
  4. Распаковывать пакеты можно через dpkg-deb:
    $ dpkg-deb -x что.deb куда/

    ОтветитьУдалить
  5. Всегда использовал dpkg -e и dpkg -x для полной распаковки пакета и быстрой правки файлов или зависимостей в контрольных файлах. А так же использовал checkinstall вместо make install для создания пакета при компиляции чего либо. Мне кажется эти утилиты стоит упомянуть.

    ОтветитьУдалить
  6. @Анонимный комментирует...

    Ошибка у вас в тексте:
    Есть такое. Исправил.

    @Анонимный комментирует...

    Распаковывать пакеты можно через dpkg-deb
    Добавил в пост. Спасибо.

    @Анонимный комментирует...
    Всегда использовал dpkg -e и dpkg -x для полной распаковки пакета
    А я просто к ar привык. Но dpkg -x в пост добавил.

    А так же использовал checkinstall
    Упомянул. Самая главная проблема начинающих дебианщиков (и особенно убунтушников) - установка программ через make install, в обход менеджера пакетов. Потом они рыдают в три ручья на форумах...

    ОтветитьУдалить
  7. Сборка пакетов из исходников в Debian - это от лукавого! Я сейчас припомню свой опыт:

    1. В deb-пакете должны быть прописаны майнтейнер и прочая чепуха, без которой (сюрприз-сюрприз!) пакет не соберется.

    2. Вы собрали, установили и думаете, что на этом всё? Не тут-то было, добрый aptitude может снести пакет ко всем чертям при установке чего-то другого. Вам знакомо такое чувство: как? где? что? я же уже ставил этот пакет!!! Ну вот такой он aptitude - весь из себя православный, а значит, патриархальный и вольнодумства не позволяющий.

    3. Поэтому срочно необходим маневр: aptitude hold package. "Что, хорошо держится? А теперь будьте любезны - отлепите!" (с) Поскольку с этого момента aptitude будет ругаться, что он не в состоянии разрулить зависимости, не снеся вашего пакета.

    4. На этом нервы мои сдали... И я открыл для себя Gentoo, а мои волосы снова стали мягкими и шелковистыми!

    ОтветитьУдалить
  8. @iv_vl комментирует...
    И я открыл для себя Gentoo, а мои волосы...
    Наглый пиар Генты?! В моём бложике??? Нет пути! ;-)

    1. В deb-пакете должны быть прописаны майнтейнер и прочая чепуха
    Стандартное policy - надо же знать, кому дать в морду за сломанный пакет :-) И потом, это всяко лучше того бедлама, который творится в RPM-ных федорах и зюзях.

    2. Вы собрали, установили и думаете, что на этом всё? Не тут-то было, добрый aptitude может снести пакет ко всем чертям при установке чего-то другого.
    Только если ты ставишь пакет старой версии - например, у меня стоит hold на IceWM, который я поставил из Lenny (придурок-майнтейнер запихнул в Squeeze айс с отломанным треем). Аптитуда тебя предупредит перед подобными манёврами, если что.


    3. Поэтому срочно необходим маневр: aptitude hold package.... aptitude будет ругаться, что он не в состоянии разрулить зависимости
    Это ложь и провокация: только если ты не влепил hold на что-нибудь типа gcc или glibc, нормально оно разруливать зависимости будет. В отличие от RPM-ов, которые любят сдаваться сразу в стиле "Ну не шмогла я, не шмогла" :-)

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


    4. На этом нервы мои сдали...
    Как-то ты быстро сдулся. Кстати, а как дела с зависимостями в генте? Как вы там живёте-то с конпелянием на каждый чих?
    Я это...не троллинга ради.... народ интересуется.

    ОтветитьУдалить
  9. @virens комментирует...
    Как-то ты быстро сдулся.
    Совсем не быстро, было это во времена Lenny, когда для получения нормального субпиксельного сглаживания нужно было патчить freetype и cairo (вот же времена были, не та тишь и благодать, что сейчас). А для меня это критично из-за плохого зрения. Ну и понеслась... В дебиане это было проблемой! Во-первых, патчи днём с огнём не найти, ибо зоркие блюстители лицензионной чистоты дебиана не дремали, во-вторых, после aptitude hold не получалось разрулить зависимости. В то время как в генте нормально функционировал оверлей lcd-filtering с нужными патчами. Тогда я понял, что гента - это свобода, а в дебиане свободы не больше, чем в православном монастыре.

    Кстати, а как дела с зависимостями в генте?
    Чтобы сломать зависимости на стабильной ветке, нужно очень постараться.

    Как вы там живёте-то с конпелянием на каждый чих?
    Для страждущих есть репозитории с бинарными пакетами.

    Я это...не троллинга ради....
    Так я и вижу, что троллинга не получилось. Тролли нынче не те, видно, завалены основной работой.

    ОтветитьУдалить
  10. @iv_vl комментирует...
    во времена Lenny, когда для получения нормального субпиксельного сглаживания нужно было патчить freetype и cairo
    Да, был такой гриб-отсосиновик. У меня плохое зрение вдаль, так что для меня оно не актуально, но тем не менее.

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

    гента - это свобода, а в дебиане свободы не больше, чем в православном монастыре.
    Ну почему: всегда можно пойти по пути Слакварщика и начать конпелять в обход APT. И будет тебе православно, патрикоугодно и ортодоксально. Правда, до следующего апдейта, да.

    Чтобы сломать зависимости на стабильной ветке, нужно очень постараться.
    Тут тоже всё более или менее предсказуемо.

    Тролли нынче не те, видно, завалены основной работой.
    А я на диете малой жирности - худею, в комментариях не троллю.
    Работы, кстати, на удивление почти нет - ждём-с ответа на наш грант, и будем ли мы распиливать бюджет. In the meantime я ваяю скрипты для автоматизации на Тикле (Tcl) - отличная штука, между прочим! После короткого вкуривания мануалов (весьма дерьмовых, кстати) пишется легко и между прочим, работает быстро и даже графический интерфейс можно прилепить (правда он страшен, как смерть водолаза).

    Можно открыть дискас на тему "Tcl VS LISP VS Lua VS Ruby" ;-)

    ОтветитьУдалить
  11. В тексте ошибка - пропущено слово:
    ......пакетный менеджер ничего о них не будет, и при обновлении системы...

    @virens комментирует...
    ...(Tcl) - отличная штука, между прочим!

    Теперь стОит ждать посты про Tcl/Tk? ;-)

    ОтветитьУдалить
  12. @Basil Orlov комментирует...

    В тексте ошибка - пропущено слово
    Есть такое - исправил. Благодарствую.

    Теперь стОит ждать посты про Tcl/Tk? ;-)
    Собственно, они уже в пути, прибывают на первую платформу по расписанию :-)

    Тикль, кстати, хорош всем, кроме некоторых встроенных косяков (он интерпретирует комментарии в коде!) и убогой (и крайне малочисленной) документации. Всего две-три книги, месиво вместо вики и пара туториалов.

    ОтветитьУдалить
  13. Собираю fpm-ом (https://github.com/jordansissel/fpm) Рекомендую!

    ОтветитьУдалить
  14. Хм... на Хабре про этот fpm статья тоже вышла буквально совсем недавно. Сетевой маркетинг? ;)

    ОтветитьУдалить
  15. Deb-пакет из бинарного файла
    очень много моментов опущено:
    Первое владельцем всех каталогов и файлов внутри ./tempprog должен быть root из группы root . Права на все файлы и каталоги 755
    Второе Если бинарник идёт в автозапуск целесообразно набросать скриптик /DEBIAN/postinst а архитектура бинарника должна соответствовать /DEBIAN/control
    Третье если собирать в домашнем каталоге команда из папки
    :~/tempprog$ sudo dpkg-deb -b ./ ~/.
    соответственно получаемый пакет генерируется каталогом выше.
    Если собирать командой из статьи внутри пакета получается одноимённый файл, который там абсолютно не нужен.
    В общем и целом конечно идея неплохая.

    ОтветитьУдалить
  16. Спасибо за полезные сведения - кое-какие тонкости я не знал.
    Вопросик есть,тоже связанный с темой пересборки пакетов,точнее с избавлением себя от регулярности этого занятия:) Насколько реально упросить хозяев Дебиана включить в пакет мелкий никому не мешающий патч? И каков алгоритм этого упрашивания? Интересует применительно к вот этому моему патчу для поддержки 866 русской кодировки в Иксах(только что адаптировал его под версию libx11-1.6.2):
    http://www.opennet.ru/openforum/vsluhforumID15/2365.html#1

    ОтветитьУдалить
  17. На совсем скорую руку:
    http://community.linuxmint.com/tutorial/view/162

    ОтветитьУдалить