Введение в сборку пакетов
Этот гайд — простое введение для тех, кто никогда раньше не собирал пакеты. Мы начнём с основ: зачем нужны пакеты, что делает Staplerfile, и соберём свой первый пакет Hello World шаг за шагом. 🚀
Что такое пакеты и зачем они нужны?
Представьте, что программа — это блюдо, которое вы хотите приготовить. У вас есть:
- ингредиенты (исходный код или готовые файлы),
- рецепт (инструкции, как всё собрать),
- коробка (готовый пакет, который можно легко установить и удалить).
Пакеты нужны потому что они:
- 📦 Удобны в установке: одна команда — и программа готова.
- 🔄 Обновляются централизованно: можно обновить все программы сразу.
- 🗑️ Легко удаляются: не оставляют «мусора» в системе.
- 🔗 Управляют зависимостями: система сама подтянет нужные библиотеки.
- 🔒 Повышают безопасность: пакеты можно проверять и поддерживать централизованно.
Что делает Staplerfile?
Staplerfile — это файл-рецепт (bash-скрипт), который описывает, как собрать и упаковать программу в пакет.
В нём указываются:
- переменные (например,
name
,version
), - шаги сборки (
prepare
,build
,package
), - источники и зависимости.
Почему именно Stapler?
Stapler похож на PKGBUILD, но работает не только в Arch Linux, а кросс-дистрибутивно. Его преимущества:
- 🌍 Кросс-дистрибутивная поддержка: один рецепт подходит для разных систем (Arch, Debian, Fedora и другие).
- 🔧 Гибкость: можно задавать зависимости и правила отдельно для разных дистрибутивов или архитектур.
- 📖 Знакомый синтаксис: переменные и функции как в PKGBUILD.
- 🛡️ Дополнительные фичи: sandbox через firejail, предупреждения для nonfree-пакетов и др.
Если вы знакомы со сборкой пакетов для Arch Linux, Staplerfile будет привычен.
Ваш первый пакет: Hello World
Это руководство поможет вам создать простой пакет для bash-скрипта с использованием Staplerfile. Мы разберем процесс создания пакета шаг за шагом, чтобы вы поняли базовую механику сборки пакетов, аналогичную работе с PKGBUILD в Arch Linux.
Шаг 1. Подготовка окружения
Создадим рабочую директорию и простой bash-скрипт, который будет основой нашего пакета.
# Создаем директорию для проекта и переходим в нее
mkdir hello-world && cd hello-world
# Создаем простой bash-скрипт, который выводит "Hello, World!"
echo '#!/bin/bash\necho "Hello, World!"' > hello.sh
# Делаем скрипт исполняемым
chmod +x hello.sh
Пояснение:
- Команда
mkdir
создает директориюhello-world
, где будут храниться все файлы пакета. - Скрипт
hello.sh
— это минимальный пример программы, которую мы упакуем. chmod +x
делает скрипт исполняемым, чтобы его можно было запускать как бинарный файл.
Теперь создайте файл Staplerfile (без расширения) в этой же директории. Это основной файл, который описывает, как собрать и упаковать наш пакет.
Шаг 2. Написание Staplerfile
Staplerfile — это файл конфигурации, который определяет метаданные пакета, его зависимости, источники и процесс сборки. Давайте разберем его по частям, добавляя подробные комментарии.
2.1. Метаданные пакета
Метаданные — это основная информация о пакете, которая помогает пакетному менеджеру понять, что это за пакет и как его установить.
# Обязательное поле: имя пакета. Должно совпадать с именем директории
name="hello-world"
# Обязательное поле: версия пакета
# Обычно версия upstream, т.е. оригинального проекта
version="1.0"
# Обязательное поле: номер релиза пакета.
# Увеличивается при обновлении пакета без изменения версии upstream
release=1
# Краткое описание пакета (обычно одна строка)
summary="Простой скрипт Hello World"
# Подробное описание пакета. Может быть многострочным, каждая строка начинается с пробела
desc="Очень
длинное
описание скрипта Hello World, которое объясняет его назначение и особенности."
Пояснение:
name
должно быть уникальным и соответствовать имени директории, чтобы избежать путаницы.version
указывает версию исходного проекта (например, версия скрипта или программы).release
— это номер сборки пакета для данной версии. Если вы обновляете сборку (например, исправляете ошибку в Staplerfile), увеличивайтеrelease
.summary
иdesc
помогают пользователям понять, что делает пакет.desc
может быть многострочным для подробного описания.
2.2. Определение архитектуры и источников
Теперь добавим информацию о поддерживаемых архитектурах и источниках файлов для пакета.
name="hello-world"
version="1.0"
release=1
summary="Простой скрипт Hello World"
desc="Очень
длинное
описание скрипта Hello World, которое объясняет его назначение и особенности."
# Указываем архитектуры, для которых предназначен пакет
architectures=('all')
# Указываем исходники для пакета
sources=("local:///hello.sh")
# Контрольные суммы для проверки целостности исходников
# 'SKIP' отключает проверку (удобно для локальных файлов или тестирования)
checksums=("SKIP")
Пояснение:
architectures=('all')
подходит для скриптов, которые не зависят от аппаратной архитектуры. Для бинарных программ можно указать конкретные архитектуры, например,('amd64' 'arm64')
.sources
определяет, откуда брать файлы для сборки. Форматlocal:///
указывает на локальный файл в директории проекта. Для удаленных файлов можно использовать URL, например,https://example.com/hello.sh
. Указанные здесь файлы попадут в директорию с исходниками —$srcdir
.checksums=("SKIP")
отключает проверку целостности. На практике рекомендуется использовать хэши (например, SHA256) для проверки исходников.
2.3. Подготовка окружения (prepare)
Функция prepare
выполняет предварительные действия перед сборкой, например, распаковку или изменение исходников
name="hello-world"
version="1.0"
release=1
summary="Простой скрипт Hello World"
desc="Очень
длинное
описание скрипта Hello World, которое объясняет его назначение и особенности."
architectures=('all')
sources=("local:///hello.sh")
checksums=("SKIP")
# [ОПЦИОНАЛЬНО]
# Функция prepare выполняется перед сборкой
# Используется для подготовки источников, например, распаковки архивов или применения патчей
prepare() {
# В данном случае мы просто выводим сообщение
# В реальных проектах здесь может быть обработка файлов из $srcdir (директория с исходниками)
echo "Подготовка завершена"
}
Пояснение:
- Переменная
$srcdir
автоматически задается системой и указывает на директорию, куда копируются файлы изsources
. - Для простого скрипта
prepare
может быть пустой или выполнять минимальные действия. В более сложных случаях здесь могут быть команды вродеtar -xf
для распаковки архивов илиpatch
для применения исправлений.
2.4. Сборка пакета (build)
Функция build
отвечает за компиляцию или преобразование исходников в готовые файлы.
name="hello-world"
version="1.0"
release=1
summary="Простой скрипт Hello World"
desc="Очень
длинное
описание скрипта Hello World, которое объясняет его назначение и особенности."
architectures=('all')
sources=("local:///hello.sh")
checksums=("SKIP")
prepare() {
echo "Подготовка завершена"
}
# [ОПЦИОНАЛЬНО]
# Функция build отвечает за сборку пакета
# Здесь выполняются команды для компиляции или обработки файлов
build() {
# В нашем случае скрипт не требует компиляции, поэтому просто выводим сообщение
# В реальных проектах здесь может быть вызов make, cmake или других инструментов сборки
echo "Сборка завершена"
}
Пояснение:
- Для bash-скрипта компиляция не требуется, поэтому функция
build
минимальна. - В сложных проектах здесь могут быть команды вроде
make
,npm build
илиpython setup.py build
. - Переменная
$srcdir
доступна для работы с исходниками.
2.5. Установка файлов (package)
Функция package()
— это сердце процесса упаковки. Здесь вы указываете, какие файлы попадут в итоговый пакет и куда они будут установлены в системе. Все файлы копируются в специальную директорию $pkgdir
, которая становится "основой" пакета (например, для .deb
, .rpm
или .pkg.tar.xz
).
$srcdir
: Директория с исходными файлами (например, распакованный архив или клонированный git-репозиторий). Здесь лежат файлы, указанные в sources.$pkgdir
: Временная директория, куда вы копируете файлы для пакета. Она имитирует структуру системы ($pkgdir/usr/bin
станет/usr/bin
при установке).
name="hello-world"
version="1.0"
release=1
summary="Простой скрипт Hello World"
desc="Очень
длинное
описание скрипта Hello World, которое объясняет его назначение и особенности."
architectures=('all')
sources=("local:///hello.sh")
checksums=("SKIP")
prepare() {
echo "Подготовка завершена"
}
build() {
echo "Сборка завершена"
}
# Функция package отвечает за установку файлов в итоговый пакет
# Файлы копируются в $pkgdir, которая становится основой для пакета
package() {
# install-binary копирует исполняемый файл в /usr/bin/ с указанным именем
# Первый аргумент — исходный файл, второй — имя в целевой системе
install-binary ./hello.sh hello-world
# Альтернативный вариант с install
# install -Dm755 "$srcdir/hello.sh" "$pkgdir/usr/bin/hello-world"
}
Пояснение:
- Команда
install-binary
— это специальная утилита внутри Stapler, которая копирует исполняемый файл в/usr/bin/
в$pkgdir
. В данном случаеhello.sh
будет установлен как/usr/bin/hello-world
.
2.6. Перечисление файлов (files)
Функция files
указывает, какие файлы должны быть включены в пакет. Это особенно важно для форматов, таких как RPM.
name="hello-world"
version="1.0"
release=1
desc="Простой скрипт Hello World"
architectures=('all')
sources=("local:///hello.sh")
checksums=("SKIP")
prepare() {
echo "Подготовка завершена"
}
build() {
echo "Сборка завершена"
}
package() {
install-binary ./hello.sh hello-world
}
# [ОПЦИОНАЛЬНО]
# Функция files перечисляет файлы, которые попадут в пакет
# Это желательно для пакетных менеджеров, таких как RPM
files() {
# files-find автоматически добавляет файлы из указанной директории
# В данном случае добавляем /usr/bin/hello-world
files-find "/usr/bin/hello-world"
}
Пояснение:
files-find
— это команда, которая автоматически регистрирует файлы в пакете. В данном случае мы указываем, что файл/usr/bin/hello-world
должен быть включен.- Для сложных пакетов можно перечислять несколько файлов или директорий.
- Эта функция особенно важна для RPM-пакетов, чтобы пакетный менеджер знал, какие файлы устанавливать и отслеживать.
Итоговый Staplerfile:
# Обязательное поле: имя пакета, совпадает с именем директории
name="hello-world"
# Обязательное поле: версия upstream (оригинального проекта)
version="1.0"
# Обязательное поле: номер релиза пакета
release=1
# Краткое описание пакета
summary="Простой скрипт Hello World"
# Подробное многострочное описание пакета
desc="Очень
длинное
описание скрипта Hello World, которое объясняет его назначение и особенности."
# Архитектуры, для которых предназначен пакет ('all' для скриптов)
architectures=('all')
# Источники файлов для сборки
sources=("local:///hello.sh")
# Контрольные суммы для проверки целостности (SKIP для тестирования)
checksums=("SKIP")
# Подготовка окружения перед сборкой
prepare() {
# $srcdir содержит исходные файлы из sources
echo "Подготовка завершена"
}
# Сборка пакета (компиляция или обработка)
build() {
# В данном случае компиляция не требуется
echo "Сборка завершена"
}
# Установка файлов в пакет
package() {
# Копируем исполняемый файл в /usr/bin/
install-binary ./hello.sh hello-world
}
# Перечисление файлов для включения в пакет
files() {
# Указываем файлы, которые попадут в пакет
files-find "/usr/bin/hello-world"
}
Шаг 3. Сборка пакета
Теперь, когда Staplerfile готов, вы можете собрать пакет. Для этого используйте команду сборки Stapler (предполагается, что у вас установлен инструмент Stapler):
stplr build -s ./Staplerfile
Пояснение:
- Команда
stplr build
выполнит все этапы: загрузку источников (в нашем случае локальный файл), выполнение функцийprepare
,build
,package
иfiles
, а затем создаст пакет (например,.deb
,.rpm
или другой). - Проверьте выходные файлы в текущей директории.
Шаг 4. Тестирование пакета
После сборки установите пакет, чтобы проверить его работу. Например, для .deb
:
sudo dpkg -i hello-world_1.0-1_any.deb
Затем выполните команду:
hello-world
Ожидаемый вывод:
Hello, World!
Пояснение:
- Установка пакета зависит от пакетного менеджера вашей системы (
dpkg
для Debian/Ubuntu,rpm
для Fedora/CentOS). - Убедитесь, что
/usr/bin/hello-world
доступен в вашей системе после установки.
Поздравляю, вы собрали первый пакет! 🎉
Дополнительные рекомендации
-
Проверка контрольных сумм
Вместо
checksums=("SKIP")
рекомендуется сгенерировать хэш файлаhello.sh
(например, с помощьюsha256sum hello.sh
) и указать его вchecksums
. Это повышает безопасность.checksums=("e7f2c7...") # Замените на реальный хэш
-
Добавление зависимостей
Если ваш скрипт зависит от других пакетов (например,
bash
), добавьте их в Staplerfile:deps=('bash')
-
Документация
Для реальных проектов добавьте файлы документации (например,
README.md
) и установите их в/usr/share/doc/hello-world/
в функцииpackage
:install -Dm644 README.md "$pkgdir/usr/share/doc/hello-world/README.md"
-
Логирование
Для отладки добавляйте больше сообщений в функциях
prepare
,build
иpackage
, чтобы понимать, что происходит на каждом этапе. -
Тестирование на разных архитектурах
Если вы указали
architectures=('all')
, проверьте, что пакет действительно работает на всех целевых системах.
Дополнительные возможности
В этом гайде мы использовали только минимально необходимый набор. Но Staplerfile поддерживает гораздо больше переменных, функций и возможностей
Примеры:
license=('MIT')
— указание лицензии (лучше использовать SPDX).maintainer="Ivan Ivanov <iivanov@example.ru>"
— кто поддерживает пакет.deps=('curl')
— зависимости для работы программы.build_deps=('make' 'gcc')
— зависимости только для сборки.opt_deps=('git: Для работы с git-репозиториями')
— опциональные зависимости.scripts=( ['postinstall']='post.sh' )
— дополнительные скрипты для установки/удаления.backup=('/etc/config')
— файлы, которые должны сохраняться при обновлении.auto_req=1
/auto_prov=1
— автоматическое определение зависимостей и предоставляемых файлов.firejailed=1
— изоляция пакета через Firejail.nonfree=1
— пометка пакета как несвободного.- переопределение под конкретный дистрибутив.
Полное описание всех полей и функций вы найдёте в спецификации Staplerfile.
Кроме этого, стоит обратить внимание на stplr-spec, который поддерживает сборку в изолированном окружении.