Перейти к основному содержимому
Версия: 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').
  • 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 и $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, который поддерживает сборку в изолированном окружении.