Перейти к основному содержимому
Версия: Canary 🚧

Введение в сборку пакетов

Этот гайд — простое введение для тех, кто никогда раньше не собирал пакеты. Мы начнём с основ: зачем нужны пакеты, что делает 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'). Подробнее про architectures.
  • sources определяет, откуда брать файлы для сборки. Формат local:/// указывает на локальный файл в директории проекта. Для удаленных файлов можно использовать URL, например, https://example.com/hello.sh. Указанные здесь файлы попадут в директорию с исходниками — $srcdir. Подробнее про sources.
  • checksums=("SKIP") отключает проверку целостности. На практике рекомендуется использовать хэши (например, SHA256) для проверки исходников. Подробнее про checksums.

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 и $pkgdir?
  • $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 доступен в вашей системе после установки.

Поздравляю, вы собрали первый пакет! 🎉

Дополнительные рекомендации

  1. Проверка контрольных сумм

    Вместо checksums=("SKIP") рекомендуется сгенерировать хэш файла hello.sh (например, с помощью sha256sum hello.sh) и указать его в checksums. Это повышает безопасность.

    checksums=("e7f2c7...") # Замените на реальный хэш
  2. Добавление зависимостей

    Если ваш скрипт зависит от других пакетов (например, bash), добавьте их в Staplerfile:

    deps=('bash')
  3. Документация

    Для реальных проектов добавьте файлы документации (например, README.md) и установите их в /usr/share/doc/hello-world/ в функции package:

    install -Dm644 README.md "$pkgdir/usr/share/doc/hello-world/README.md"
  4. Логирование

    Для отладки добавляйте больше сообщений в функциях prepare, build и package, чтобы понимать, что происходит на каждом этапе.

  5. Тестирование на разных архитектурах

    Если вы указали 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, который поддерживает сборку в изолированном окружении.