View on GitHub

Methodics of GNU/Linux application software development

Practical materials for learning application software development on Linux

В данном разделе мы рассмотрим основные идеи установки и пакетирования (в смысле оформление дистрибутива по правилам GNU), принятые в Linux.

Терминология

На протяжении всего курса мы создавали проект, состоящий из множества связанных элементов. Теоретически, для того, чтобы поделиться созданной утилитой, мы можем разместить каталог с исходниками в публичном репозитории и оставить все остальные действия для непосредственных пользователей. Однако в такой ситуации у нас отсутствует понятие установки как таковой: пользователь должен сам не только скачать архив с данными, но и скомпилировать их, собрать (пусть и с помощью автосборочных команд типа configure-make) проект; в процессе сборки может оказаться, что у пользователя не хватает библиотек для работы, не работают какие-то связи из-за неправильной сборки. Поэтому по дороге к использованию самого проекта ещё придётся самому редактировать код.

Установка же подразумевает работу из коробки (или почти из коробки) уже собранных бинарников, распределённых по системе. Для распределения файлов по системе для корректной их работы в Unix-подобных системах введён стандарт иерархии файлов в файловой системе (Filesystem_Hierarchy_Standard), на которую настроена работа операционной системы.

Варианты установки

Рассмотрим разные популярные варианты установки проектов в систему.

Самый классический вариант - установка в полном соответствии с FHS данных проекта в системные папки /usr/bin, /usr/lib64 и т.д. Данный способ гарантирует работу всех систем, и, собственно, потому и является классическим, поскольку работа со всеми системными утилитами настроена под именно такое распределение файлов. Однако данный способ имеет одну большую проблему - установка в системные папки требует прав root при работе, а это, потенциально, даёт полный доступ к любым вторжениям в систему со стороны устанавливаемого ПО. И только разработчику известно, что установит или удалит в системе его make install (знаменитое удаление французского языка из системы). Кроме того, даже рабочее и безопасное ПО может конфликтовать с уже установленным ПО дистрибутива.

Для избежания конфликтов с системой появился ещё один метод установки - в специальные выделенные каталоги /usr/local/bin, /usr/local/lib64 и т. д. Такая установка, вообще говоря, не соответствует FHS, она также требует root-прав для установки и, кроме того, вероятность конфликтов нового ПО с уже установленным более вероятен. Но данный способ не конфликтует с базовыми системами и поэтому используется в больших системах, подразумевающих установку огромного количества пакетов в неё.

Для установки проекта без прав root-а располагать файлы можно в директориях пути $HOME/.local/. Такие установки являются локальными и доступными каждому пользователю по отдельности, отчего в нашей системе могут происходить установки одних и тех же приложений. Кроме того, “дополнительные действия” программ из-за зависимостей на локальные установки каждого пользователя могут не заработать. Такой способ установки полезен для систем, ориентированных на разработчика (поскольку для именно разработки требуется отдельное (а иногда и не одно) независимое пространство установки), а вот для пользователей работа с таким относительно изолированным пространством, для которого надо прописать все связи всех файлов отдельно, будет проблематичным

Гарантированно неконфликтующий ни с какими утилитами способ установки - под правами root в директорию /opt/<приложение>/. Из минусов такой установки - нужно явно указывать в $PATH /bin-директорию нашего проекта, чтобы запускать его, а также проводить дополнительную настройку при старте (подтягивание всех зависимостей из нестандарных расположений), обычно - через shell-сценарии. Такая схема используется в сложных проектах, требующих притаскивания с собой разных библиотек и бинарников.

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

Самая непробиваемая и независимая ни от чего стратегия - полная статическая компоновка и установка его. Такой бинарник не требует никаких прав root, зависимостей, правильных установок, поскольку буквально заработает из любого места системы. Статическая линковка подходит для либо очень больших, либо очень маленьких приложений, которые должны работать везде, лишь бы ядро ОС могло их исполнять. Кроме того, такой схемой можно удобно собирать разные версии приложений.

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

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

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

Можно воспользоваться параметрами autotools для выбора установочных данных

Для тестовой установки после локальной сборки хорошо подойдут сценарии из libtool, поддерживающий установку со стороны окружения за счёт сценариев .la-сценариев и т.д.

Введение в пакетирование —

Ручная (или с помощью сборочных сценариев) установка (любым из выше указанных методов)- это один из способов начала работы с готовым продуктом. Однако для разработки под Linux самым правильным является создание пакета.

Пакетирование, как способ работы с проектами, обязано во многом Свободному Лицензированию и Открытой разработке. Именно они позволяют создавать огромные неконфликтующие инфраструктуры пакетов, основываясь на открытом исходном коде собираемых компонентов системы, для которой капет предназначается.

Сам пакет - это архив с составляющими исходниками, которые раскладываются по основным директориям системы (под root-ом), при этом сборка и проверка данных, а также подключение библиотеки пред- и постустановочные сценарии проходят без root-а

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

Множество пакетов объединяется в дистрибутивы - срезы из общего множества пакетов работающих наборов, корректно взаимодействующих друг с другом и обеспечивающих функционал целой системы (приложения / ОС и т.д.)

В следующем разделе мы кратко обсудим основные шаги пакетирования в Linux.

Домашнее задание

Финальный проект. Взять какое-нибудь домашнее задание, или сделать новый проект любого уровня тупости. В проекте должны быть (в любом невырожденном объёме):