Debian как собрать из исходных кодов. Учимся собирать deb-пакеты

Сегодня я расскажу на абстрактном примере как правильно создать *.deb пакет для Ubuntu/Debian. Пакет мы будем делать бинарный. Пакеты, компилирующие бинарники из исходников здесь не рассматриваются: осилив изложенные ниже знания, в дальнейшем по готовым примерам можно понять суть и действовать по аналогии:)

В статье не будет никакой лишней возни «вручную»: формат пакета эволюционировал в достаточно простую, а главное - логичную структуру, и всё делается буквально на коленке, с применением пары специализированных утилит.

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

Для тех, кто не хочет вдаваться в мощную систему установки софта в Linux, рекомендую посетить сайт проги CheckInstall : она автоматически создаёт deb-пакет из команды «make install» ;) А мы вместе с любопытными -

Источники

Информация надёргана из многих мест, но вот два основных:
  • Debian.org: Debian Policy Manual - официальная
  • Ubuntu Wiki: PackagingGuide/Basic
В статье подробно изложены основы создания пакетов, достаточные для получения достаточно мощного управления установкой приложений. Более продвинутые фичи опущены, но предложены прямые ссылки на документацию для интересующихся.
Статья не является копией или переводом какой-либо документации: это - коллекция знаний, валявшихся в виде заметок, а теперь оформленная в виде статьи. Для ясности везде есть примеры, разъяснения на пальцах, найденные мной удобные фичи и некоторые типичные ошибки, которые можно совершить по незнанию.

Подготовка

Зачем это всё?
Да, CheckInstall умеет создавать рабочий пакет, но он не поддерживает все вкусности, на которые способны deb пакеты:) А именно:
  • Скрипты, выполняющиеся до, после и вместо установки пакета:)
  • Автоматическое управление конфигурационными файлами: пакет не позволит затереть старые конфиги новыми без спроса
  • Работа с шаблонами: возможность задавать пользователю вопросы при установке (!!!)
  • Изменение файлов других пакетов
Что потребуется
Конечно, для создания полноценного пакета хватит архиваторов tar, gz, ar, но можно исключить лишнюю возню, и воспользоваться инструментами, созданными для облегчения жизни:)
Ставим:
$ sudo apt-get install dpkg debconf debhelper lintian
Что мы будем делать
Для примера будет рассмотрен некий скрипт /usr/bin/super.sh. Не важно что внутри, главное - как он появится на правильном месте:)
Подготовка папки
В домашнем каталоге (или где удобно) создаём папку, в которой будут лежать все файлы будущего пакета: mkdir ~/supersh . Далее будем называть её корень пакета .
В корне пакета создаём папку «DEBIAN» (заглавными буквами, это важно!). Эта папка содержит управляющую генерацией пакета информацию, и не копируется на диск при установке пакета.
Также корневая папка пакета содержит будущий «корень диска»: при установке пакета все файлы (кроме папки «debian») распаковываются в корень /. поэтому наш скрипт должен лежать по такому пути, относительно корня пакета: «usr/bin/super.sh»
Белым по чёрному:
mkdir -p ~/supersh/DEBIAN # управляющая папка
mkdir -p ~/supersh/usr/bin # путь к скрипту
cp super.sh ~/supersh/usr/bin/ # копируем наш скрипт в нужное место
В итоге имеем:
supersh/DEBIAN/
supersh/usr/
supersh/usr/bin/
supersh/usr/bin/super.sh

Создание пакета: DEBIAN/*

Как я уже сказал, папка DEBIAN содержит файлы, используемые при установке. Здесь я опишу (с примерами) каждый файл.
Для создания полноценного пакета достаточно контрольного файла «control», все остальные используются либо для прикрепления текстовой информации (changelog, лицензия), либо для управления расширенными возможностями установки приложений.
Из описанных ниже файлов в папке DEBIAN/* выбираем необходимые, и заполняем согласно инструкции:)
В наше примере реально используется только обязательный DEBIAN/control .
DEBIAN/control: Основная информация
control - центральный файл пакета, описывающего все основные свойства. Файл - текстовый, состоящий из пар «Атрибут: значение». Можно использовать комментарии: символ "#" в начале строки (возможность была добавлена в версии dpkg >= 1.10.11, надеяться на комментарии не стоит:).
В таблице приведены все поля, определённые для контрольного файла. Обязательные поля выделены жирным : без них пакет не будет считаться составленным верно.
Атрибут Описание Примеры
- основные -
Package: Имя пакета: - только латиница, цифры, и дефис. Имя используется при установке: apt-get install Package: supersh
Version: Версия пакета (и проги внутри). Используется для определения «обновлять ли».
Формат принят такой: <версия_программы>-<версия_пакета> .
Рекомендую всегда указывать версию пакета: при изменении структуры пакета цифра увеличивается на единичку.
Допустимые символы достаточно вольные: можно использовать дату и буквы. Примеры смотрите сегодня в своём репозитории:)
Version: 1.0-1
Version: 2009.12.12-1
Provides Имя приложения (возможно, виртуальное), регистрируемое в системе в результате установки этого пакета.
Используется редко: в основном, если нужно изменить имя пакета, или если более одного пакета предлагают одинаковый функционал. Например, пакеты Apache и nginx предоставляют возможность демона httpd: Provides: httpd
Вы наверняка сталкивались с ошибкой при попытке установки: «is a virtual package». Это оно и есть:)
Provides: supersh
Maintainer Имя и почта мэйнтейнера пакета: человека, который «дебианизировал» приложение.
Формат произвольный, но принято имя
Maintainer: o_O Tync
Architecture Архитектура процессора, для которой предназначен пакет.
Допустимые значения: i386, amd64, all, source
all используется для скриптов: они же портативные, верно? :)
source используется для компилируемых пакетов с исходниками
Architecture: all
Section Определяет задачу, для которой приложение обычно используется (группа приложений).
Возможные значения: admin, base, comm, contrib, devel, doc, editors, electronics, embedded, games, gnome, graphics, hamradio, interpreters, kde, libs, libdevel, mail, math, misc, net, news, non-free, oldlibs, otherosfs, perl, python, science, shells, sound, tex, text, utils, web, x11
Section: misc
Description Описание пакета.
Описание состоит из двух частей: короткое описание (70 символов) на той же строке, и длинное описание на последующих строках, начинающихся с пробела .
В расширенном описании все переводы строки игнорируются. Для вставки \n используется одиночная точка.
Description: Short.
␣Long
␣goes here.
␣.
␣New line.
- связи и зависимости -
Depends Список пакетов через запятую, которые требуются для установки этого пакета.
После имени пакета можно в круглых скобках указать ограничение на версию, используя операторы: <<, =, >>, <=, >=. Если оператор не указан - используется >=
Depends: dpkg, libz (>= 1.2.3), jpeg (= 6b), png (< 2.0)
Pre-Depends Список пакетов, которые требуются в процессе установки этого пакета.
Эти зависимости могут потребоваться для скриптов установки пакета: например, пакет flash-installer требует wget
Можно использовать ограничения на версию (см. Depends).
Pre-Depends: wget (>= 1.0)
Conflicts Список пакетов, которые не могут быть установлены одновременно с этим.
Установка не удастся, если хоть один из перечисленных пакетов уже будет установлен.
Conflicts: crapscript
Replaces Список пакетов, файлы которых модифицируются этим пакетом.
Требуется в случае создания «пакета-патча», изменяющего что-либо: в противном случае при замене файлов чужого пакета возникнет ошибка при установке. У меня, например, такой пакет патчит UT2004 и убирает звук наводящейся ракетницы:)
Replaces: ut2004
Recommends Список пакетов, рекомендуемых к установке
Эти пакеты не обязательны, но обычно используются вместе с текущим
Recommends: superplatform
Suggests Список пакетов, предлагаемых к установке.
Эти пакеты не обязательны, но с ними прога работает ещё лучше:) По идее, менеджер пакетов должен предлагать установить их.
Suggests: supersh-modules
Build-Depends (Только для Architecture: source)
Список пакетов, требуемых для компиляции исходников.
То же, что и Depends, но логически отделено.
Build-Depends: cmake
- экстра -
Installed-Size Размер файлов пакета в килобайтах.
Просто цифра, округлённая до ближайшего целого. Используется менеджером пакетов для определения суммарного требуемого объёма на диске.
Installed-Size: 3
Priority Приоритет пакета: насколько он важен в системе
Возможные значения: extra, optional, standard, important, required (такие пакеты не удаляются вообще!).
Priority: optional
Esssential Если установить этот атрибут в значение «yes», пакет нельзя будет удалить. Esssential: yes
Origin Строка: откуда получены программы в пакете. Обычно используется URL сайта автора, почта или имя. Origin: brain
X-Source Полная ссылка на *.tar.gz архив с исходниками X-Source: ...*.tgz

Да, вот такие солидные возможности у контрольного файла:)
А в нашем примере он выглядит так:
Package: supersh
Version: 1.0-1
Section: misc
Architecture: all
Depends: bash, sed (>= 3.02-8)
Maintainer: o_O Tync
Description: Super Shell Script
␣A super example script.
␣.
␣It does nothing:)
DEBIAN/copyright: / лицензия
Текст лицензии. Файл не обязателен, но лучше подчеркнуть своё авторство;)
DEBIAN/changelog: история изменений
Changelog в специальном формате: используется dpkg для получения номера версии, ревизии, дистрибутива и важности пакета. Лучше посмотреть в ;) а я лишь приведу пример:
supersh (1.0-1) stable; urgency=medium

O_O Tync Sun, 13 Dec 2009 00:11:46 +0300

DEBIAN/conffiles: список файлов конфигурации
Обычно пакеты содержат болванки конфигурационных файлов, например, размещаемых в /etc. Очевидно, что если конфиг в пакете обновляется, пользователь потеряет свой отредактированный конфиг. Эта проблема легко решается использованием папок типа «config.d», содержимое которых включается в основной конфиг, заменяя собой повторяющиеся опции.
Файл «DEBIAN/conffiles» позволяет решить проблему иначе: он содержит список файлов конфигурации (по одному на строке). Если в текущей версии пакета один из этих файлов обновляется, то пользователь получает предупреждение о конфликте версий конфигов, и может выбрать: удалить, заменить, или сделать merge.
С этой ситуацией наверняка сталкивался каждый линуксоид, копавшийся в конфигах:) А ноги растут отсюда.
На каждой строке должен быть полный абсолютный путь до каждого конфига. Например:
/etc/supersh/init.conf
/etc/supersh/actions.conf
DEBIAN/dirs: список папок для создания
«Список абсолютных путей к папкам, которые требуются программе, но по каким-либо причинам не создаются.» - гласит официальная документация. На практике – здесь перечисляются все папки, так или иначе используемые программой: и где лежат бинарники, и которые используются программой.
По одной на строке. Например:
/var/log/supersh
/var/lib/supersh
Удобно использовать для создания нескольких пустых папок.
DEBIAN/menu: создание пунктов меню
Хитрый файл для создания пунктов меню. У меня он так и не заработал:) Складывается ощущение, что его содержимое используется либо в необычных оконных менеджерах, либо в каком-то консольном меню… или же использовалось ранее и было забыто:)
Пример:
?package(supersh):needs="text" section="Applications/Programming" title="Super Shell Script" command="/usr/bin/super.sh"
TODO: узнать зачем нужно. Об этом написано в man5 menufile , честно говоря я не вникал:)
UPD: Правильный способ добавления пункта меню
Файл /DEBIAN/menu создаёт неизвестно что и непонятно где: элементы графического меню всё равно не создаются. Поэтому будем делать правильно:)
В /usr/share/applications видим кучку *.desktop файлов: это и есть пункты меню. Они представляют собой текстовые файлы с синтаксисом наподобие ini-файла. Открываем, учимся, делаем так же и кладём получившийся *.desktop файл в usr/share/applications/ . Иконка для него должна лежать в usr/share/pixmaps .
После этого в postinst скрипт нужно добавить выполнение команды обновления меню update-menus:
if [ "$1" = "configure" ] && [ -x "`which update-menus 2>/dev/null`" ] ; then
update-menus
fi

Работа со скриптами установки пакета будет рассмотрена далее.
Спасибо Condorious за наводку:)

DEBIAN/md5sums: контрольные суммы файлов
Используется для проверки целостности пакета. Важный файл.
Заполняется так (cwd=корень пакета):
$ md5deep -r usr > DEBIAN/md5sums
DEBIAN/watch: мониторинг сайта, откуда была скачана прога
Функция полезна, если Вы мэйнтейните от нескольких десятков пакетов, и уследить за всеми обновлениями сложно.
Файл содержит инструкции для программ uscan и uupdate. Используя эту возможность, можно следить за сайтом, откуда были получены исходники пакета, и обеспечивать контроль качества дистрибутива в целом.
Пример:
# Site Directory Pattern Version Script
ftp.obsession.se /gentoo gentoo-(.*)\.tar\.gz debian uupdate
DEBIAN/(preinst|postinst|prerm|postrm): скрипты установки
Всего можно создать до четырёх скриптов в одном пакете:

Обратите внимание, что ошибки, возникающие в этих скриптах никак не логируются : ничего интереснее кода возврата скрипта нигде не сохраняется, и логирование необходимо делать вручную! Пользователи одного моего пакета терпели неудачу при установке на Linux Mint, и не было даже возможности попросить у них лог ошибок (которого нету) чтобы выдебагать причину:)
Рекомендую использовать в начале каждого скрипта следующую болванку: она будет сохранять в syslog все возникающие ошибки.
#!/bin/bash
set -e # fail on any error
set -u # treat unset variables as errors

# ======[ Trap Errors ]======#
set -E # let shell functions inherit ERR trap

# Trap non-normal exit signals:
# 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
trap err_handler 1 2 3 15 ERR
function err_handler {
local exit_status=${1:-$?}
logger -s -p "syslog.err" -t "ootync.deb" "supersh.deb script "$0" error code $exit_status (line $BASH_LINENO: "$BASH_COMMAND")"
exit $exit_status
}

Ваш код установочного скрипта...

WARNING: болванка пока не тестировалась широко, проверьте лишний раз! На невозможность отладки наткнулся совсем недавно:)

DEBIAN/templates: шаблоны для диалогов
Как уже было сказано, в скрипте DEBIAN/config можно задавать пользователю вопросы: ввести строку, выбрать один из вариантов, поставить галочку,… Этим занимается «библиотека» bash функций debhelper пакета debconf, умеющая кроме этого ещё массу полезных вещей. Здесь их не рассматриваю:)
Файл DEBIAN/templates содержит данные, используемые при выводе диалоговых окон (GUI или ncurses). Файл содержит блоки, разделённые пустой строкой. Каждый блок определяет ресурсы, используемые в одном конкретном диалоговом окне.
Шапка для всех типов диалогов стандартная:
Template: supersh/template-name
Type: string
Default: Default-value
Description: Dialog-title
␣Dialog-text

Template - уникальный (в пределах одного пакета) идентификатор шаблона. Если в скрипте нужно вызвать определённый диалог - используется именно это имя.
Type - тип шаблона. Определены такие типы: string, password, boolean, select, multiselect, text, note, error.
Default-value - значение по умолчанию: пользователь может просто согласиться с ним.
Description - как и в контрольном файле, состоит из двух полей: короткое описание, и длинный текст. Первое - это заголовок «окна», второе - более развёрнутое описание того, что требуется от пользователя. Рекомендуется не использовать слов вроде «введите», а сразу суть: «Приветствие скрипта», «Точка монтирования»,…

Тип Описание шаблона
string Приглашение на ввод текстовой строки
password Приглашение на ввод пароля.
Для этого типа шаблона нет значения Default по понятным причинам:)
boolean Галочка:) Имеет строковое значение «true» или «false»
select Возможность выбора одного из нескольких вариантов.

Choices: yes, no, maybe
multiselect Возможность выбора нескольких вариантов галочками.
Варианты предлагаются в дополнительном атрибуте шаблона:
Choices: sex, drugs, rock-n-roll
text Выводит на экран текст: некоторая не очень важная информация
note Выводит на экран текст: важная информация
error Выводит на экран текст: очень важная информация, критическая.

Для шаблонов text, note, error также нет значения Default, так как они лишь отображают информацию:)
Поиграемся с следующим шаблоном:
Template: supersh/greeting
Type: string
Description: Welcome message
␣The message you wish the script to welcome you with.
Default: Greetings, my master!
Основы использования debconf и debhelper
Это лишь работоспособные наброски. В оригинале почитать о шаблонах и работе с ними можно здесь: man 7 debconf-devel:)
Чтобы использовать шаблоны в своём скрипте настройки DEBIAN/config, необходимо сначала подключить функции debhelper:
. /usr/share/debconf/confmodule . Также этот файл нужно подключить в скрипте postinst: иначе скрипт DEBIAN/config вообще не выполнится!
Эти функции доступны в пакете debconf, не забудьте включить его в зависимости!
Примитивный пример использования. Файл DEBIAN/config
#!/bin/bash -e

# Подключение команд debconf

Case "$1" in
configure|reconfigure)
# Запрос


# Обработка ответа

greeting="$RET"
echo "$greeting" > /etc/supersh/greeting.txt
;;
*)
echo "config called with unknown argument \`$1"" >&2
exit 1
;;
esac
# Запрос
db_input medium "supersh/greeting" || true # инициализация
db_go || true # вывод запроса на экран

# Обработка ответа
db_get "supersh/greeting" # Получение значения в переменную $RET
greeting="$RET"
echo "$greeting" > /etc/supersh/greeting.txt

Здесь уже кроется неприятная засада: обратите внимание, что функции db_input передаётся приоритет диалога medium. Для debconf можно установить минимальный приоритет: диалоги с приоритетом ниже которого не отображаются, а берётся значение по умолчанию (Default шаблона)! Чтобы этого ТОЧНО не случилось - используем приоритет critical:) Кроме того, при установке из GUI порог вывода вопросов выше, и многие из них не отображаются вообще.
Возможные приоритеты: low - всегда используется default, medium - дефаулт обычно вполне подходит, high - дефаулт нежелателен, critical - внимание пользователя жизненно важно.
|| true используется чтобы скрипт не помер из-за ключика "-e" переданного bash.
В этом скрипте тоже рекомендуется использовать ту болванку для отлова ошибок, иначе с распространяемым пакетом могут возникнуть проблемы при отладке:)
Все тонкости использования debconf (функции, способы, параметры, коды ошибок) описаны в достаточно многословном мане: man debconf-devel .

И последнее: при удалении пакета командой purge - debconf должен также вычистить из своей базы сведения о пакете. Например, он сохраняет выбор пользователя при запросах db_input.
Чтобы вычистить эти данные, нужно в postinst-скрипт добавить следующее:
if [ "$1" == "purge" ] && [ -e /usr/share/debconf/confmodule ] ; then
. /usr/share/debconf/confmodule
db_purge
fi

Собираем пакет! :)

Ура! Все нужные файлы созданы, лежат по нужным папочкам. Теперь пора собирать пакет:)
Первое, что нужно сделать - это рекурсивно выставить всем файлам в корне пакета пользователя и группу root:root (или другие, если потребуется). Это нужно затем, что файлы пакета упаковываются в tar.gz архив который сохраняет и права доступа к файлам, и владельца. Потому нужно выполнить:
$ sudo chown -R root:root .
Однако делать это не обязательно. Есть отличная команда fakeroot которая при создании архива подменит владельца файлос root-ом.
В нашем примере, скрипт должен иметь бит выполнимости.
Потом выходим на папку назад, чтоб было видно корневую папку пакета, и пакет создаётся лёгким пинком сам:
$ fakeroot dpkg-deb --build supersh
Созданный пакет необходимо переименовать, чтобы он соответствовал порядку именования *.deb пакетов: <имя пакета>_<версия>_<архитектура>.deb
$ mv supersh.deb supersh_1.0-1_all.deb
Всё, пакет готов!
Автоматическая проверка пакета
Существует утилита lintian, позволяющая проверить пакет и выявить типичные ошибки в его структуре. Делается это так:
$ lintian supersh_1.0-1_all.deb
Установка пакета
$ sudo dpkg -i supersh_1.0-1_all.deb

Создаём собственный репозиторий пакетов

Теперь у нас есть собственный пакет. Когда их будет несколько, и тем более - с зависимостями, окажется, что намного удобнее быстренько поднять собственный локальный микро-репозиторий, и включить его в список источников менеджера пакетов:) Здесь я опишу быстрый HowTo «как создать свой репозиторий». Идею будет легко развить, почитывая соответствующую документацию:)
Сперва установим помощника:
$ sudo apt-get install reprepro
Описание будущего репозитория
Центр репозитория - его описание. Главное в нём - список компонент репозитория. Мы создадим компоненты «soft» и «games».
Выберите папку для будущего репозитория. Все действия производятся из её корня.
Создаём файл conf/distributions следующего содержания:
Description: my local repository
Origin: Ubuntu
Suite: testing
AlsoAcceptFor: unstable experimental
Codename: karmic
Version: 5.0
Architectures: i386 amd64 source
Components: soft games
UDebComponents: soft games

В нашем деле создания простого репозитория все поля не играют принципиальной роли, и используются лишь для визуального определения «что есть что»:)

Создание репозитория
Репозиторий описан! Теперь сгенерируем болванку на основе описания. Команды выполняются в корне репозитория:
$ reprepro export
$ reprepro createsymlinks
И добавим готовый репозиторий в /etc/apt/sources.list:
deb file:///path/to/repo/ karmic soft games
Этот репозиторий можно также расшарить при помощи веб-сервера.
Управление пакетами в репозитории
В корень репозитория кладём *.deb файлы для добавления, и добавляем их в компоненту soft дистрибутива karmic:
reprepro -C soft includedeb karmic *.deb
теперь пакеты доступны из менеджера пакетов:)
Удаление пакетов:
reprepro -C soft remove karmic supersh

Финиш

В статье рассмотрены материалы по созданию deb пакетов. Акцент сделан на моментах, для которых в сети нет достаточно наглядного описания. Надеюсь, что моя попытка изложить просто и понятно не провалилась:)
Домашнее задание:)) - вполне неплохо документированные вещи, которые легко найти в man"ах и статьях:
  • Создание source пакетов, компилирующих исходники: на примере Zabbix об этом отлично рассказал хабраюзер mahoro в своей статье
  • Debconf, debhelper в конфигурационных скриптах: читаем маны по debconf-devel и debhelper. Они также позволяют создать скелет пакета командой dh_make.
  • Продвинутые способы создания документации в пакетах: файлы DEBIAN/docs, DEBIAN/manpage.*
  • Создание init скриптов
  • Управление заданиями cron
  • Подписывание репозитория ключём gpg

Введение

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

    Архив control.tar.gz, содержащий скрипты, написанные майнтенером пакета, использующиеся при установке/удалении пакета, а так же другие служебные файлы;

    Архив data.tar.gz, содержащий двоичные файлы программы, ради которой создан пакет;

    Файл debian-binary.

Поскольку содержимое пакета может в будущем измениться (будет новый номер версии в debian-binary), то собирать deb-пакет при помощи программ tar, gzip, ar не рекомендуется и этот вариант в статье рассматриваться не будет.

Собирается пакет программой dpkg из специально подготовленной структуры каталогов:

    Path/to/dir/file1

    Path/to/dirX/fileX

    Файлы и каталоги, предназначенные для установки в систему. Их расположение в архиве соответствует положению их в файловой системе если считать от корня. Например файл usr/share/doc/package/copyright в deb-архиве после установки будет находиться в /usr/share/doc/package/copyright (все они будут упакованы в архив data.tar.gz);

    Каталог DEBIAN/, содержащий служебную информацию о пакете. Содержимое этого каталога при сборке будет упаковано в архив control.tar.gz;

Создание пакета Geany (A fast and lightweight IDE)

configure

Команда configure запущенная с ключем –help выводит список параметров, которые можно передать ей.

$ ./configure ... checking dependency style of gcc... (cached) gcc3 checking for g++... no checking for c++... no checking for gpp... no checking for aCC... no checking for CC... no checking for cxx... no checking for cc++... no checking for cl.exe... no checking for FCC... no checking for KCC... no checking for RCC... no checking for xlC_r... no checking for xlC... no checking whether we are using the GNU C++ compiler... no checking whether g++ accepts -g... no checking dependency style of g++... none configure: error: No C++ compiler not found. Please install a C++ compiler.

Просматриваем вывод команды, если в конце строки "no" это означает, что в системе нет необходимых для компиляции данной программы вспомогательных программ и библиотек. Вывод малоинформативен -нет явного соответствия между ошибкой и пакетом который требуется до установить. Зная, что в Ubuntu часто пакеты с библиотеками бывают разбиты на два типа:

    динамическая библиотека, необходимая для работы уже скомпилированных программ;

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

Устанавливаем требуемые пакеты.

# aptitude install autoconf automake libtool autotools-dev dpkg-dev fakeroot intltool-debian intltool ... Следующие НОВЫЕ пакеты будут установлены: autoconf automake autotools-dev build-essential{a} dpkg-dev g++{a} g++-4.3{a} gettext{a} intltool intltool-debian libltdl7-dev{a} libstdc++6-4.3-dev{a} libtool m4{a} 0 пакетов обновлено, 14 установлено новых, 0 пакетов отмечено для удаления, и 0 пакетов не обновлено. Необходимо получить 10,2MБ архивов. После распаковки 35,9MБ будет занято. Хотите продолжить? Y ...

Проверяем. Снова запускаем./configure.

$ ./configure ... checking pkg-config is at least version 0.9.0... yes checking for GTK... configure: error: Package requirements (gtk+-2.0 >= 2.8.0) were not met: No package "gtk+-2.0" found Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.

Ошибка. Требует пакет gtk+-2.0. Как показали поиски на английских форумах - пакет все же называется libgtk2.0-dev. Ставим. Как показывает вывод ниже - лучше найти УЖЕ скомпилированный DEB пакет - благо на это есть реальные шансы.

# aptitude install libgtk2.0-dev ... Следующие НОВЫЕ пакеты будут установлены: debhelper{a} html2text{a} libatk1.0-dev{a} libcairo2-dev{a} libdirectfb-dev{a} libdirectfb-extra{a} libexpat1-dev{a} libfontconfig1-dev{a} libfreetype6-dev{a} libglib2.0-dev{a} libgtk2.0-dev libice-dev{a} libjpeg62-dev{a} libmail-sendmail-perl{a} libpango1.0-dev{a} libpixman-1-dev{a} libpng12-dev{a} libpthread-stubs0{a} libpthread-stubs0-dev{a} libsm-dev{a} libsys-hostname-long-perl{a} libsysfs-dev{a} libx11-dev{a} libxau-dev{a} libxcb-render-util0-dev{a} libxcb-render0-dev{a} libxcb1-dev{a} libxcomposite-dev{a} libxcursor-dev{a} libxdamage-dev{a} libxdmcp-dev{a} libxext-dev{a} libxfixes-dev{a} libxft-dev{a} libxi-dev{a} libxinerama-dev{a} libxrandr-dev{a} libxrender-dev{a} po-debconf{a} x11proto-composite-dev{a} x11proto-core-dev{a} x11proto-damage-dev{a} x11proto-fixes-dev{a} x11proto-input-dev{a} x11proto-kb-dev{a} x11proto-randr-dev{a} x11proto-render-dev{a} x11proto-xext-dev{a} x11proto-xinerama-dev{a} xtrans-dev{a} zlib1g-dev{a} 0 пакетов обновлено, 51 установлено новых, 0 пакетов отмечено для удаления, и 0 пакетов не обновлено. Необходимо получить 11,4MБ архивов. После распаковки 39,4MБ будет занято. Хотите продолжить? Y

Проверяем. Снова запускаем./configure. И видим ниже счастье:) Команда выполнилась успешно!!!

$ ./configure ... Install Geany in: /usr/local Using GTK version: 2.16.1 Build with GTK printing support: yes Build with plugin support: yes Use virtual terminal support: yes Use (UNIX domain) socket support: yes Configuration is done OK.

make

Компилируем в бинарные файлы

Установка пакета (2 способа)

    1 -й способ -стандартный (подходит для любого дистрибутива Unix). Лучше использовать во FreeBSD при установке из портов. В Ubuntu это приведет к засорению системы, так как менеджеры пакетов (apt, aptitude и т.д.) не будут видеть установленной программы. Соответственно удалять ее придется вручную. $ make install

    2 -й способ - использование утилиты checkinstall # aptitude install checkinstall # man checkinstall NAME checkinstall - Track installation of local software, and produce a binary manageable with your package management software. ...

    Так как сборку пакета производим под Ubuntu -нас интересуют ключи:

    D Create a Debian package.

    Полная последовательность команд:

    $ cd /home/darkfire/deb/geany/geany-0.17 $ ./configure $ make $ sudo bash # дальнейшие команды должны выполняться от root # checkinstall -D ... ********************************************************************** Done. The new package has been installed and saved to /home/darkfire/deb/geany/geany-0.17/geany_0.17-1_i386.deb You can remove it from your system anytime using: dpkg -r geany ********************************************************************** ...

    Пакет geany_0.17-1_i386.deb собран и готов к установке.

Создание пакета Eric Python IDE

Создаем пакет Eric IDE с поддержкой русского языка. Скачиваем и распаковываем исходники и русификацию. Перед компиляцией установим необходимые для запуска Eric пакеты.

# aptitude install bicyclerepair libqscintilla2-3 libqt3-i18n libqt4-assistant libqt4-help libqt4-webkit libqt4-xmlpatterns $ mkdir -p /home/darkfire/deb/eric4ide $ cd /home/darkfire/deb/eric4ide $ wget http://downloads.sourceforge.net/project/eric-ide/eric4/4.3.5/eric4-4.3.5.tar.gz $ wget http://downloads.sourceforge.net/project/eric-ide/eric4/4.3.5/eric4-i18n-ru-4.3.5.tar.gz?use_mirror=sunet $ tar -xzvf eric4-4.3.5.tar.gz $ tar -xzvf eric4-i18n-ru-4.3.5.tar.gz $ cd /home/darkfire/deb/eric4ide/eric4-4.3.5/ $ sudo bash # checkinstall python install.py checkinstall 1.6.1, Copyright 2002 Felipe Eduardo Sanchez Diaz Duran Эта программа распространяется на условиях GNU GPL The package documentation directory ./doc-pak does not exist. Should I create a default set of package docs? [y]: Готовится документация к пакету...OK Пожалуйста напишите описание пакета. Закончите ваше описание пустой строкой или EOF. >> Создаем пакет Eric IDE с поддержкой русского языка. >> ***************************************** **** Debian package creation selected *** ***************************************** Этот пакет был создан с использованием данных значений: 0 - Maintainer: [ root@ubuntuatom ] 1 - Summary: [ Создаем пакет Eric IDE с поддержкой русского языка. ] 2 - Name: [ eric4 ] 3 - Version: [ 4.3.5 ] 4 - Release: [ 1 ] 5 - License: [ GPL ] 6 - Group: [ checkinstall ] 7 - Architecture: [ i386 ] 8 - Source location: [ eric4-4.3.5 ] 9 - Alternate source location: 10 - Requires: 11 - Provides: [ eric4 ] Введите номер для изменения параметра или нажмите ВВОД для продолжения: ... Compiling eric/uninstall.py ... Installing eric4 ... Installation complete. ======================== Установка успешно завершена ====================== Copying documentation directory... ./ ./README-i18n.txt ./THANKS ./README grep: /var/tmp/tmp.hxkpsnHJSB/newfile: No such file or directory Some of the files created by the installation are inside the build directory: /home/darkfire/deb/eric4ide/eric4-4.3.5 You probably don"t want them to be included in the package, especially if they are inside your home directory. Do you want me to list them? [n]: Исключить их из пакета? (ответить ДА-хорошая идея) [y]: Файлы копируются во временный каталог...OK Stripping ELF binaries and libraries...OK Сжимаются страницы руководства...OK Построение списка файлов...OK Собирается Debian-пакет... Удаляются временные файлы...OK Записывается пакет с резервной копией...OK Удаляется временный каталог...OK ********************************************************************** Done. The new package has been installed and saved to /home/darkfire/deb/eric4ide/eric4-4.3.5/eric4_4.3.5-1_i386.deb You can remove it from your system anytime using: dpkg -r eric4 **********************************************************************

Устанавливаем скомпилированный пакет:

Dpkg -i eric4_4.3.5-1_i386.deb

Неудача

при запуске -возникает ошибка

# eric4 Traceback (most recent call last):

File "/usr/lib/python2.6/dist-packages/eric4/eric4.py", line 20, in from PyQt4.QtCore import QTextCodec, SIGNAL, SLOT, qWarning, \

ImportError: No module named PyQt4.QtCore

Частенько возникает необходимость собрать пакет с какими либо файлами, из которых скомпилировать ничего нельзя. В моём случае это чаще всего самописные bash-скрипты, файл с public ключами ssh… Ещё интересная идея так же паковать архивы.

В рассмотренном ниже примере мы создадим один deb пакет с аж тремя вкусными штуками:
1) конфигурационные файлы nginx с нашего сервера
2) файл с public ключами для авторизации обладателей закрытой части этих ключей на сервере рутом
3) скрипт /usr/bin/ourscript.sh (неважно что он делает, по сути)

Принцип одинаковый, просто мне удобно показать сразу три примера. Пакет будет называться nginxsuperconfig

Предрекая вопросы «а зачем тебе fakeroot, если всё делаешь рутом?». Удобно . А главное — просто и быстро.

Начнем-с с создания нужных каталогов и копирования в эту структуру нужных нам файлов. Каталог DEBIAN должен быть написан именно большими буквами. Остальные каталоги — воссоздание структуры необходимых нам файлов с условным корнем в виде каталога /root/builder/nginxsuperconfig/. То есть всё, что лежит в этом каталоге (кроме DEBIAN) просто распакуется в корень. Как будто вы создадите tarболл с содержимым этого каталога и распакуете его в корень.
root@builder:~# mkdir -p /root/builder/nginxsuperconfig/DEBIAN
root@builder:~# mkdir -p /root/builder/nginxsuperconfig/etc
root@builder:~# mkdir -p /root/builder/nginxsuperconfig/usr/bin
root@builder:~# mkdir -p /root/builder/nginxsuperconfig/root/.ssh
root@builder:~# cp -r /etc/nginx /root/builder/nginxsuperconfig/etc
root@builder:~# cp /usr/bin/ourscript.sh /root/builder/nginxsuperconfig/usr/bin/
root@builder:~# cp /root/.ssh/authorized_keys /root/builder/nginxsuperconfig/root/.ssh/

Теперь нам понадобится написать файлы, описывающие свойства пакета. Обязательным является только файл DEBIAN/control. Для примера я ещё напишу несколько скриптов — один из них будет выполняться перед установкой пакета, второй — по окончанию и ещё один — при удалении пакета.

Напишем файл control:
root@builder:~# editor /root/builder/nginxsuperconfig/DEBIAN/control
Я перечислю обязательные поля. На самом деле туда можно много чего написать, но это уже лучше поискать в сети:
Package: nginxsuperconfig
Version: 1.0-1
Section: misc
Priority: extra
Maintainer: inkvizitor68sl
Architecture: all
Depends: nginx, openssh-server, bash
Description: Example package
Package with nginx configs, ssh keys, example script.

Немного прокомментирую.
Package — название пакета.
Version — версия. Через дефис пишем «номер сборки». Например, если вы слегка поправили файл в содержимом, но версия пакета не сменилась. В данном случае мы сами решаем какая у нас версия, потому можно не париться и всегда ставить версия-1
Section — для случаев рассмотренных в примере больше всего подходит misc
Priority — аналогично, подходит extra
Maintainer — ваше имя/ник и почта
Depends — в простейшем случае через запятые перечисляем имена пакетов, которые должны быть установлены, чтобы ваш пакет работал. В нашем случае — nginx (мы же для него конфиг льем), openssh-server (а зачем ключи, если ssh сервера нет?), bash, без которого не запустится наш скрипт.
Description — строка с кратким описанием пакета (не более 70 символов). Следующие строки — полное описание пакета. Перенос строки — точка.

Теперь создадим нужные скрипты.
Выполняемый перед инсталляцией:
root@builder:~# editor /root/builder/nginxsuperconfig/DEBIAN/preinst
#!/bin/bash
mv /etc/nginx /etc/nginx.bak
mv /root/.ssh/authorized_keys /root/.ssh/authorized_keys.old

Выполняемый после инсталляции:
root@builder:~# editor /root/builder/nginxsuperconfig/DEBIAN/postinst
#!/bin/bash
/etc/init.d/nginx restart
chmod +x /usr/bin/ourscript.sh

Выполняемый после удаления:
root@builder:~# editor /root/builder/nginxsuperconfig/DEBIAN/postrm
#!/bin/bash
rm -r /etc/nginx
mv /etc/nginx.bak /etc/nginx
rm /root/.ssh/authorized_keys
mv /root/.ssh/authorized_keys.old /root/.ssh/authorized_keys

Ещё можно создать выполняемый перед удалением скрипт:
root@builder:~# editor /root/builder/nginxsuperconfig/DEBIAN/prerm

В общем-то всё готово к сборке пакета:
root@builder:~# cd /root/builder/
root@builder:~# fakeroot dpkg-deb --build nginxsuperconfig

Мы получим файл nginxsuperconfig.deb. Неплохо его ещё переименовать, чтобы в названии содержалась версия:
root@builder:~# mv nginxsuperconfig.deb nginxsuperconfig_1.0-1.deb

Вот в общем-то и всё. Напоминаю, что это простейший пример. Я не ставил перед собой задачи написать очередной огромный непонятный мануал про сборку пакетов. Я постарался описать именно простейший способ собрать свой собственный deb пакет с данными. Ах да, не забудьте, что таким способ можно собрать метапакет для личного использования. То есть пакет, который сам ничего не содержит, зато по зависимостям тянет всё нужное.
Куда слать вопросы, думаю, знаете =)

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

С помощью deb пакетов довольно просто можно организовать деплой на ваши сервера. При этом у вас будет версионирование и все такое. Я чаще всего использую ubuntu, поэтому речь будет именно о deb пакетах, которые можно установить/удалить с помощью утилит apt .

Что же нужно сделать, для создания своего репозитория с пакетами? Можно воспользоваться тем же launchpad.net , например. Но, последнее время, он не очень развивается и выглядит ненадежно. К тому же, его удобно использовать для своих не коммерческих разработок, но использовать его для дистрибуции корпоративного ПО будет проблематично.

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

Сборка пакетов

Для всех своих проектов я использую . Структура проекта выглядит примерно так:

Project/ |- bin/ | |- project |- src/ | |- github.com/ | |- 4gophers/ | |- project/ | |- main.go |- vendor/

Когда я запускаю gb build , то все бинарники собираются в папке bin . Таким образом, все что нам нужно - это просто добавить спецификацию нашего будущего deb пакета прям в папку с проектом:

Mkdir project/DEBIAN touch project/DEBIAN/control

В результате будет такая структура:

Project/ |- DEBIAN/ | |- control |- bin/ | |- project |- src/ |- vendor/

В файле control нужно указать информацию о нашем пакете. Не забывайте про пустую последнюю строку:

Package: project Priority: optional Section: devel Installed-Size: 100 Maintainer: Ivan Ivanov Architecture: i386 Version: 1.0 Depends: libc6 (>= 2.1) Description: Short description here Long description here

  • Package - имя вашего пакета
  • Priority - приоритет пакета (optional, extra, standard, important, required) для обычных программ лучше ставить optional
  • Section - раздел к которому относится данный пакет (admin, base, comm, contrib, devel, doc, editors, electronics, embedded, games, gnome, graphics, hamradio, interpreters, kde, libs, libdevel, mail, math, misc, net, news, non-free, oldlibs, otherosfs, perl, python, science, shells, sound, tex, text, utils, web, x11)
  • Installed-Size - размер файлов пакета в килобайтах
  • Maintainer - имя и email создателя пакета
  • Architecture - архитектура процессора, для которой предназначен пакет (i386, amd64, all, source, all)
  • Version - версия пакета
  • Depends - в данном поле необходимо указать имена пакетов, от которых зависит ваш пакет (например, библиотеки)
  • Description - в первой строке пишем короткое описание пакета, в остальных более подробно

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

Стоит отметить, что такой подход к созданию deb пакетов не самый правильный. Конечно, в нашем случае мы осознанно идем на этот шаг, но вам нужно понимать, что в deb пакет попадет все содержимое папки project , в том числе папки src , vendor и так далее. Конечно, можно скопировать файлы в другую папку, и даже написать скрипт для этого, но все уже придумано до нас. Более правильный способ - это использовать утилиты dh_make и dpkg-buildpackage .

Теперь можно собирать пакет. Для этого на уровень выше выполним команду:

Dpkg-deb -z8 -Zgzip --build project

На уровень выше будет создан файл project.deb , который можно устанавливать с помощью команды:

Sudo dpkg -i project.deb

Свой репозиторий пакетов

Теперь переходим к самому интересному. Как же нам распространять наши пакеты? Запустим свой сервер репозиториев, конечно же. А для этого воспользуемся сервером apt репозиториев deb-simple .

Это действительно простой сервер, который устанавливается всего одной командой:

Go get github.com/esell/deb-simple

Если go не установлен на той машине, где вы собираетесь запустить сервер с репозиториями, то вы можете собрать бинарник локально и просто скопировать его. Кроме этого, можно использовать docker.

Затем нужно запустить сервер. Это можно сделать с помощью docker, но мне больше нравится использовать supervisord . Вот пример моей конфигурации сервиса:

Command=/home/user/go1.5/bin/deb-simple directory=/home/user/deb-simple/ autorestart=true stdout_logfile=none

Тут важно указать путь к бинарнику(command) и рабочую папку(directory), в которой мы разместим наш конфиг.

Сервер deb-simple поддерживает https, но пока нам это не нужно. Для репозиториев нужно создать папку repo . Наш конфиг conf.json будет выглядит так:

{ "listenPort" : "9090", "rootRepoPath" : "/home/user/deb-simple/repo", "supportedArch" : ["all","i386","amd64"], "enableSSL" : false, "SSLcert" : "server.crt", "SSLkey" : "server.key" }

Чтобы загрузить пакет в свой репозиторий, нужно воспользоваться HTTP API самого сервиса:

Curl -XPOST "http://localhost:9090/upload?arch=amd64" -F "[email protected]"

Точно так же для удаления:

Curl -XDELETE "http://localhost:9090/delete" -d "{"filename":"project.deb","arch":"amd64"}"

Нам осталось добавить наш сервер репозиториев к списку в /etc/apt/source.list.d/ . Можно создать отдельный файл с содержимым:

Deb http://my-hostname:9090/ stable main

Теперь запускайте sudo apt-get update и устанавливайте свои программы сколько душе угодно.

Зачастую некоторый пакет имеется в ветках unstable и experimental , однако его нет в ветках stable /testing . Программу поставить очень хочется, а обновлять полсистемы страшновато или нежелательно.

Для таких случаев есть замечательный ресурс backports.org , однако его использование во многом похоже на прямое использование веток unstable и иногда доставляет бОльшие проблемы из-за периодически возникающих конфликтов между backports и unstable.

В большинстве случаев установить пакет из unstable и experimental можно, используя пересборку пакета в своем окружении. Делается это довольно несложно, и данное руководство предназначено для того, чтобы помочь начинающему пользователю в этом вопросе. Для примера мы разберем вариант с установкой пакета fluxbox из experimental -ветки.

Установим инструменты для сборки:

#aptitude install devscripts

Gpg-ключ и выполним экспорт некоторых переменных окружения, связанных с ним:

export [email protected] export DEBFULLNAME="yourfullname" export [email protected]

Настройка apt-get

Прежде всего, нам необходимо настроить apt-get на работу с src-репозитариями Debian. Для этого добавьте в Ваш файл /etc/apt/sources.list следующие строки:

deb-src http://ftp.debian.org/debian testing main contrib non-free deb-src http://ftp.debian.org/debian sid main contrib non-free deb-src http://ftp.debian.org/debian experimental main contrib non-free

Зеркало пакетов, разумеется, можете выбрать любое - то, которым наиболее часто пользуетесь. После изменения файла /etc/apt/sources.list сделайте традиционный

#apt-get update

Немного теории

Что представляет собой src-пакет в системе Debian?

Src-пакет для debian - это исходные тексты программы, которые любезно предоставлены автором под той или иной лицензией, дополненные несколькими скриптами (которые предоставлены сопровождающим пакета), обеспечивающими сборку пакета.

Все скрипты, файлы и т.п., относящиеся к сборке пакета в системе Debian, традиционно располагаются в подкаталоге debian/ вместе с исходными текстами.

Src-пакет Debian обычно состоит из нескольких файлов:

    package-version.dsc - текстовый файл, включающий в себя перечень остальных необходимых файлов;

    package-version.orig.tar.gz - архив с исходными текстами программы;

    package-version.diff.gz - патч на архив с исходными текстами программы, добавляющий в них вышеупомянутый каталог debian/, а так же, возможно, содержащий исправления внесенные в исходные тексты сопровождающим.

Примечание : Некоторые включают каталог debian/ прямо в архив с исходными кодами. Это в основном касается программ разработанных специально для Debian. В таком случае вместо файлов .orig.tar.gz и .diff.gz будет один файл package-version.tar.gz .

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

$ apt-get source package

для нашего случая с fluxbox это будет выглядеть так:

$ apt-get source fluxbox Чтение списков пакетов... Готово Построение дерева зависимостей... Готово Нужно загрузить 1033kB архивов с исходными текстами. Получено:1 http://ftp.debian.org experimental/main fluxbox 0.9.15.1+1.0rc2-1 (dsc) Получено:2 http://ftp.debian.org experimental/main fluxbox 0.9.15.1+1.0rc2-1 (tar) Получено:3 http://ftp.debian.org experimental/main fluxbox 0.9.15.1+1.0rc2-1 (diff) Получено 1033kB за 1m38s (10,5kB/c) gpg: Signature made Втр 04 Июл 2006 17:05:39 MSD using DSA key ID E160649A gpg: Can"t check signature: public key not found dpkg-source: extracting fluxbox in fluxbox-0.9.15.1+1.0rc2 dpkg-source: unpacking fluxbox_0.9.15.1+1.0rc2.orig.tar.gz dpkg-source: applying ./fluxbox_0.9.15.1+1.0rc2-1.diff.gz

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

$ apt-cache policy <имя пакета>

В результате этого действия, как видно из приведенного выше лога, были скачаны нужные файлы с зеркала (которое мы прописали в /etc/apt/sources.list ) и произведена распаковка исходников и наложение патча в .diff.gz .

Данную операцию необязательно было проделывать с помощью apt-get , можно было пойти на страничку пакета , скачать файлы по ссылке Downloads (внизу страницы) и распаковать командой

$ dpkg-source -x fluxbox_0.9.15.1+1.0rc2-1.dsc

Также можно использовать утилиту dget, которая скачает весь пакет и сразу распакует исходники:

dget www.path.to/fluxbox_0.9.15.1+1.0rc2-1.dsc

Немного об устройстве каталога debian/

Все действия по сборке пакетов выполняются из каталога с исходными текстами, который получился при распаковке src-архива. В этом каталоге расположен и каталог debian/.

В данном каталоге нас прежде всего будут интересовать два файла:

    debian/rules - этот скрипт осуществляет собственно сборку пакета (и представляет собой обычный Makefile);

    debian/control - этот текстовый файл снабдит нас некоторой информацией, которая нам понадобится ниже;

Прежде всего в последнем файле нас интересует одна строка, для нашего пакета fluxbox она выглядит так:

    Build-Depends: libx11-dev, libxext-dev, libxft-dev, libxinerama-dev, libxpm-dev, libxrandr-dev, x-dev, libxt-dev, debhelper (>=4.1.0), libxft-dev, libx11-dev, libxext-dev, libxft-dev, libxinerama-dev, libxpm-dev, libxrandr-dev, x-dev, libimlib2-dev, libgtk2.0-dev, cdbs

как видим это просто список пакетов которые необходимы нам при сборке.

Зависимости для сборки

Это может оказаться как самый простой вопрос, так и самый сложный. Ситуация состоит в следующем. Сопровождающий пакета, как правило, является человеком, хорошо разбирающимся во внутреннем устройстве Debian, поэтому сопровождающие зачастую раньше других переходят на использование testing/unstable веток. Кроме того, аплоад пакетов в Debian происходит прежде всего в unstable, а потому сопровождающий часто оттестировал сборку своего пакета только под testing/unstable. Довольно редко авторы программ указывают версионные зависимости для своих детищ, поэтому не всегда удаётся проставить правильные версии, и они могут быть как завышены, так и занижены. Выяснять, с какой версией той или иной библиотеки перестанет собираться программа занимает много времени и сил, а зачастую и не очень нужно.

Установка зависимостей для сборки

Простой случай: все получилось с первого раза

Если у Вас apt-get настроен так, как было указано выше, то в большинстве случаев установка зависимостей может быть сделана одной командой:

# apt-get build-dep fluxbox

Для рассматриваемого нами пакета fluxbox все необходимое будет установлено без проблем, и можно переходить к разделу (ниже) Сборка пакета .

Требуемые зависимости отсутствуют в моем дистрибутиве

Здесь возможны два варианта.

    Вариант, дающий 100%-й результат, но, возможно, требующий проделать больше работы: просматриваем строку Build-Depends , о которой речь шла выше, и смотрим, какие библиотеки или утилиты отсутствуют в нашем дистрибутиве. Как правило, их перечень не такой большой чтобы испугать настойчивого человека (одна-две). Собираем эти библиотеки или утилиты по этому хауту (рекурсивно;)).

    В случае если в строке Build-Depends указана какая-то отсутствующая в нашем дистрибутиве версия пакета, то можно попробовать понизить требования сопровождающего, отредактировав файл debian/control . Попробуйте уменьшить номер версии требуемой библиотеки или утилиты, указанный сопровождающим, на тот что у Вас имеется. Перед тем как двигаться по этой пути, проглядите каталог с исходными текстами на наличие файлов INSTALL или README. В этих файлах авторы программы иногда описывают зависимости своего детища и если уж автор программы указал версионную зависимость, то скорее всего попытка ее понизить ни к чему не приведет.

Для того чтобы узнать, что еще не установлено для сборки пакета, запустите утилиту dpkg-checkbuilddeps в каталоге с исходными текстами. Эта утилита выведет список того что требуется для сборки, но еще не установлено в Вашей системе. Для перехода к следующему шагу Вам необходимо добиться того чтобы утилита dpkg-checkbuilddeps не выдавала сообщений о неудовлетворенных зависимостях. Можете попробовать собрать неудовлетворенную зависимость или понизить требования к номеру версии или покомбинировать эти два варианта.

Сборка пакета

Простая сборка

Итак, все что необходимо нам для сборки, установлено. Осталось, собственно, собрать пакет. Для этого нам понадобится утилитка fakeroot , установите ее, если она у Вас еще не установлена.

Переходим в каталог с распакованным src-пакетом и даем команду:

  • $ dch -i

Отдельно надо рассмотреть вопрос о том, какую версию указывать в changelog.

  • Это не должна быть версия, встречающаяся в официальном репозитории (чтобы не создавать путаницы)
  • Если вы делаете просто бэкпорт, то версия должна быть младше той версии, на основе которой собран пакет (чтобы не возникло проблем, когда этот пакет попадет в testing, затем в stable и вы попробуете сделать dist-upgrade). Добавьте строку ~backports1 к номеру версии в таком случае. Позже, если в репозитариях окажется пакет с таким же номером версии, то ваша система произведет его обновление. Цифра 1 в данном случае может означать номер Вашей сборки, а слово backports может быть заменено на любое другое, которое будет более информативным.

Исходя из этого, правильным будет добавить к версии -какаятострока1 , если вы что-то существенно дорабатывали, или ~какаятострока1 , если делали бэкпорт.

$ fakeroot ./debian/rules binary или $ dpkg-buildpackage -rfakeroot или #debuild

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

Проблемы на этом шаге могли возникнуть только в двух случаях:

  • Вы что-то не (так) сделали на предыдущих шагах (например, понизили зависимость, а реально этого делать было нельзя);
  • Вы наткнулись на ошибку в src-пакете. Такое тоже иногда случается. Бывает, что пакеты не собираются, например, из за "неверно" установленного umask . Вообще, сборка пакетов от umask зависеть не должна, но этот баг почему-то довольно часто встречается в Debian.

Вернитесь на несколько шагов назад и повторите попытку.

Если есть только архив с исходниками

Итак, у нас есть только fluxbox-0.9.15.tar.bz2. Обычно выполняюncz следующие действия: Предварительно подготавливаю рабочую директорию:

mkdir ~/src/fluxbox mkdir ~/src/fluxbox/0.9.15 cd ~/src/fluxbox/0.9.15 wget "http://<путь до файла>" (можно конечно и просто через браузер скачать но обычно так быстрее)

Получаем файл fluxbox-0.9.15.tar.bz2. Немного забегая вперёд, обработаем файл программой gzip.

bunzip2 fluxbox-0.9.15.tar.bz2 gzip fluxbox-0.9.15.tar

Получим fluxbox-0.9.15.tar.gz, переименуем:

mv fluxbox-0.9.15.tar.gz fluxbox_0.9.15.orig.tar.gz

(т.е. разделили имя и версию подчёркиванием и после версии добавили слово orig: fluxbox_0.9.15.orig.tar.gz) Теперь распаковываем его (но ни в коем случае не удаляем!):

tar zxvf ./fluxbox_0.9.15.orig.tar.gz cd fluxbox-0.9.15

Для корректной сборки нужно, чтобы корневая директория содержала не только название, но и версию! Ниже будем считать директорию ~/src/fluxbox/0.9.15/fluxbox-0.9.15 корневой директорией исходников. Далее выполняем «черновую» сборку. Т.е. делаем, как обычно

./configure --prefix=/usr && make

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

Если есть только deb-пакет

Распаковываем пакет в папку /tmp/program/

$ dpkg -x program*.deb /tmp/program

Чтобы распаковать информацию о пакете, нужно выполнить:

mkdir /tmp/program/DEBIAN $ dpkg -e program*.deb /tmp/program/DEBIAN

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

$ dpkg - b /tmp/program program-new*.deb

Дебианизация

Cмысл всей этой процедуры - создать директорию debian в корне исходников, с нужными файлами конфигурации и скриптом(ами). Для этого, в корне исходных текстов (~/src/fluxbox/0.9.15/fluxbox-0.9.15), выполним:

dh_make Type of package: single binary, multiple binary, library, kernel module or cdbs? s Maintainer name: Frank Email-Address: [email protected] Date: Wen, 20 Mai 2011 12:40:33 +0200 Package Name: fluxbox Version: 0.9.15 License: GPLv3 Type of Package: Single Hit to confirm:

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

Could not find fluxbox_0.9.15.orig.tar.gz Either specify an alternate file to use with -f, or add --createorig to create one.

В таком случае советую прервать dh_make (Ctrl+C) и переименовать архив, как описано выше. Но мы с вами молодцы и всё у нас прошло без ошибок - появился каталог debian в корне исходников, посмотрев его содержимое, Вы увидите кучу файлов (расширение.ex) с примерами на все случаи жизни. Будем считать, что программа у нас простая, обычно ни один из этих файлов не нужен. Первым делом нужно добавить описание программы в файле debian/control :

Description:

Вместо и (без угловых кавычек) нужно вписать описание,что это за программа. Именно эти сведения увидит пользователь, когда посмотрит описание пакета в synaptic"е. Второй момент - это поправить файл debian/rules в секции binary-arch: нужно раскомментировать(т.е. убрать # в начале строки)

  • dh_install

без этого мы получим пустой пакет. Обычно этих настроек достаточно для сборки пакета с одной программой, которая не содержит разделяемых библиотек, т.е. только бинарник в /usr/bin и данные в /usr/share. Теперь, соберём пакет:

dpkg-buildpackage -rfakeroot

в директории выше, т.е. в ~/src/fluxbox/0.9.15, мы получим файлы:

cd .. ls -1 fluxbox_0.9.15-1.diff.gz fluxbox_0.9.15-1_i386.changes fluxbox_0.9.15-1_i386.deb fluxbox_0.9.15.orig.tar.gz

Установка пакета

После того, как пакет собран, его осталось установить командой:

dpkg -i имя_пакета.deb

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

Сборка с созданием чистых образов систем

На самом деле, для того, чтобы собрать пакет правильно, его надо собирать в минимальной системе, где стоят только build-essential и зависимости этого пакета. Тогда, во-первых, не будет никаких накладок из-за того, что у вас в системе стоят некоторые пакеты вообще неизвестно откуда и непонятно каких версий (и в итоге в зависимостях у бинарного пакета могут оказаться пакеты версий, отсутствующих в том дистрибутиве, под который вы хотите собрать пакет), а во-вторых, вы избежите накладок (крайне редких, но все же), когда установленный лишний пакет как-то (читай негативно и не всегда очевидно) влияет на сборку.

В качестве решения подойдет chroot с чистым окружением… Испугались? Все уже украдено до нас.

Сборка пакета в системе pbuilder

Довольно неплохо упрощает данный процесс интерактивная программа pbuilder . Установите пакет pbuilder , затем откройте на редактирование /etc/pbuilderrc и пропишите адрес Вашего любимого репозитория.

Выполните команды:

# pbuilder update # pbuilder create --distribution """sarge"""

система готова к употреблению.

Вместо имени sarge подставьте название Вашего дистрибутива.

теперь чтобы собрать пакет для выбранного дистрибутива дайте команду:

# pbuilder build package-version.dsc

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

Сборка пакета в системе cowbuilder

сowbuilder является из пакета cowdancer – это аналог pbuilder, только образ сборочной системы он хранит не в tar.gz а в развернутом виде, а при сборке копирует этот образ с использованием техники copy-on-write, что ускоряет сборку.

Пример конфига /etc/pbuilderrc:

BUILDPLACE=/var/cache/pbuilder/build/ USEPROC=yes USEDEVPTS=yes USEDEVFS=no BUILDRESULT=/var/cache/pbuilder/result/ #у меня кэширующий apt-cacher, пожтому я отключил кэширование пакетов внутри pbuilder #APTCACHE="/var/cache/pbuilder/aptcache/" APTCACHE="" REMOVEPACKAGES="" HOOKDIR="" export DEBIAN_FRONTEND="noninteractive" DEBEMAIL="Alexander GQ Gerasiov < [email protected] >" BUILDSOURCEROOTCMD="fakeroot" PBUILDERROOTCMD="sudo" DEBBUILDOPTS="" APTCONFDIR="" BUILDUSERID=1000 BUILDUSERNAME=gq export LOGNAME=gq BINDMOUNTS="" unset DEBOOTSTRAPOPTS export PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin" export SHELL=/bin/bash DEBOOTSTRAP="cdebootstrap" PKGNAME_LOGFILE_EXTENTION="_$(dpkg --print-architecture).build"

Создать образ системы можно и без использования конфига:

# cowbuilder --create --distribution sid --architecture i386

Теперь логинимся в чистую систему:

# cowbuilder --login --save # aptitude install devscripts

Виход из окружения стандартен, собраные пакеты искать в /var/cache/pbuilder.

exit или Сtrl+D

Сборка пакета в чистом окружении

Как теперь собрать пакет в нужном окружении. Вначале из нашего каталога <имя пакета>-<версия апстрим> с измененной версией и поправленными build-depends собираем сурцовый пакет новой версии:

dpkg-buildpackade -rfakeroot -S

Переходим каталогом выше, где собрался файлик <имя пакета>_<версия>.dsc (где версия, это уже наша версия с “~backport”) и говорим

pbuild --dist sarge <имя пакета>_<версия>.dsc

Если произошла ошибка (например из-за проблем с зависимостями), то возвращаемся к шагу 1 и исправляем ошибки. Если все прошло нормально, то собранные пакеты окажутся в каталоге /var/cache/pbuilder/results. Вот собственно и все.

Для обновления образов (особенно актуально для testing) я использую команду

pbuild --dist etch --update

Пример скрипта автоматизации: || ||

Пример скрипта автоматизации для нескольких релизов: || ||

Удаление зависимостей для сборки

Для этого можно использовать deborphan :

$ deborphan или $ deborphan -guess-dev или сразу удалить: # deborphan -guess-dev | xargs apt-get remove -purge -y

или же скриптом(проверено PavloRudyj):

# aptitude markauto $(apt-cache showsrc PACKAGE_NAME | grep Build-Depends | perl -p -e "s/(?:[\[(].+?[\])]|Build-Depends:|,|\|)//g")