Bash by example / Bash в примерах: Part 3: Exploring the ebuild system
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Введение в систему ебилдов. undeceived 21.02.11 в 22:12 |
+1 |
|
Я с нетерпением ждал этой третьей и последней статьи цикла "Bash в примерах", потому что в первых двух частях мы разобрались в основах программирования и теперь наконец можем сосредоточиться на более интересных моментах, таких как разработка програм и дизайн приложений. undeceived 21.02.11 в 22:35 |
||
|
Так как я являюсь создателем Gentoo Linux, а также человеком, создавшим Funtoo Linux - в число моих прямых обязанностей входит контроль того, что все пакеты операционной системы (похожие на пакеты RPM) правильно собраны и работают совместно без конфликтов. Как вы, вероятно, знаете, стандартная система Linux представляет из себя не единое унифицированное дерево исходников (как BSD), а состоит из примерно 25 с хвостиком основных пакетов, работающих совместно. Некоторые из пакетов включают в себя: undeceived 21.02.11 в 22:45 |
||
|
Пакет Описание Daemon786 09.02.11 в 10:38 |
||
|
Примечание: undeceived 21.02.11 в 22:49 |
||
|
Каждый пакет входящий в тарболл поддерживаеться независимыми разработчиками, или командами разработчиков. Для создания дистрибутива, каждый пакет отдельно загружается, компилируется и упаковывается. Каждый раз когда пакет исправляется, обновляется или улучшается, компиляция и упаковка повторяются (это происходит довольно часто). Для исключения повторяющихся сложных действий при создании и обновлении пакетов, я создал ебилд систему, написанную полностью на Bash. Для увеличения ваших знаний Bash, я показываю применение распаковки и компилирования частей в ебилд системе, шаг за шагом. Объясняю каждое действие, а также почему оно имеет такой вид. В конце этой статьи, даже если вы имеете опыт крупномасштабных проектов в bash програмировании, вы также имеете возможность получить объяснения по созданию завершенной автоматически созданной системы. bugzy 28.02.11 в 15:16 |
||
|
Почему bash? Daemon786 08.02.11 в 14:22 |
||
|
Bash - существенный компонент системы ебилдов Gentoo Linux. Он был выбран в качестве основново языка ебилдов по ряду причин. Во-первых он имеет простой и знакомый синтаксис, что особенно хорошо подходит для вызова внешних программ. zlyoha 02.05.11 в 12:02 |
||
|
Процесс развертывания bugzy 01.03.11 в 14:22 Обзор процесса сборки neumann16 10.05.11 в 08:04 |
||
|
Прежде чем мы рассмотрим систему ебилдов, давайте посмотрим что принимает участие в компиляции и инсталляции пакета. В нашем примере, мы будет рассматривать пакет "sed", являющийся стандартной GNU утилитой для потокового редактирования текста и входящий во все Linux дистрибутивы. В начале скачаем архив с исходными кодами (sed-3.02.tar.gz) (смотри Ресурсы). Мы будем хранить этот архив в /usr/src/distfiles, данную директорию будем использовать в значении переменной $DISTDIR. $DISTDIR это директория где находятся все наши оригинальные архивы с исходниками; это большое хранилище исходных кодов. neumann16 10.05.11 в 08:12 |
||
|
Следующим нашим шагом будет создание временной директории work, в которой будут находиться разархивированные исходные коды. Мы будем ссылаться на эту директорию позже, используя переменную $WORKDIR. Перейдите в директорию в которой мы имеем право на запись и выполните следующие команды: neumann16 10.05.11 в 08:30 |
||
|
$ mkdir work Daemon786 24.01.11 в 13:14 |
||
|
Когда развернеться архив тарбола, будет создан каталог sed-3.02, содержащий все ресурсы. Мы будем ссылаться на этот каталог позже с помощью переменной $SRCDIR. Для компиляции программы наберите следующее: bugzy 01.03.11 в 14:21 Архив разархивируется, создав директорию sed-3.02, содержащую все исходные коды. Мы будем позже ссылаться на директорию sed-3.02, используя переменную $SRCDIR. Для компиляции программы введите следующее: neumann16 10.05.11 в 08:41 |
||
|
$ cd sed-3.02 neumann16 10.05.11 в 12:20 |
||
|
Мы пропустим шаг "make install", поскольку мы рассмотрим только шаги распаковки и компиляции в этой статье. Если мы захотели бы написать bash-скрипт для выполнения всех этих шагов, то он выглядел бы примерно так: neumann16 10.05.11 в 12:37 |
||
|
#!/usr/bin/env bash bugzy 28.02.11 в 17:44 |
||
|
Обобщение кода bugzy 01.03.11 в 14:14 |
||
|
Хотя этот скрипт работает, он не очень гибкий. В основном bash-скрипт содержит только список всех команд, которые были набраны в командной строке. Хоть это решение и работает, неплохо было бы создать общий скрипт, который можно быстро настроить для распаковки и компиляции любого пакета, просто изменив несколько строк. Таким образом, он помогает создателям пакетов делать гораздо меньше работы во время добавления новых пакетов в дистрибутив. Давайте добъемся этого, используя множество различных переменных, делая наш скрипт более общим: neumann16 10.05.11 в 13:24 |
||
|
#!/usr/bin/env bash bugzy 01.03.11 в 14:13 |
||
|
Мы добавили много переменных в скрипт, но он продолжает выполнять тоже самое. Хотя, сейчас для компиляции любого стандартного архива основанного на GNU autoconf, мы можем просто скопировать этот скрипт в новый файл (с соответствующим именем, означающим название нового пакета, который он компилирует), и затем изменить значения переменных $A и $P на нужные. Все остальные переменные автоматически принимают правильные значения, и скрипт работает как надо. Хоть это и удобно, есть еще одно улучшение, которое можно сделать с кодом скрипта. Данный код намного длиннее чем оригинальный "нетронутый" сценарий, который мы создали. Поскольку одной из целей для любого проекта должно стать снижение сложности для пользователя, было бы неплохо резко сократить код, или, по крайней мере лучше его организовать. Мы можем сделать это, выполнив изящный трюк - мы разделим код на два отдельных файла. Сохраните этот файл как sed-3.02.ebuild: neumann16 10.05.11 в 13:57 |
||
|
#the sed ebuild file -- very simple! Daemon786 24.01.11 в 13:17 # Файл sed ebuild - очень просто! bugzy 28.02.11 в 17:48 # ебилд файл для sed -- очень простой! neumann16 10.05.11 в 14:02 |
+1 | |
|
Наш первый файл тривиален, и содержит только те переменные окружения, которые должны быть изменены для различных пакетов. Теперь рассмотрим второй файл, который содержит мозг операции. Сохраните это в файл "ebuild" и сделайте его исполняемым: neumann16 11.05.11 в 10:18 |
||
|
#!/usr/bin/env bash neumann16 11.05.11 в 10:25 |
||
|
Теперь когда мы разбили нашу систему сборки на два файла, я уверен, вам станет интересно как это работает. В принципе, для компиляции sed, наберите: neumann16 10.05.11 в 17:55 |
||
|
$ ./ebuild sed-3.02.ebuild Daemon786 24.01.11 в 13:18 |
||
|
После запуска "ebuild", он сначала пытается выполнить "source" переменной $1. Что это означает? Из предыдущей главы, напомню, что $1 является первым аргументом командной строки -- в этом случае, sed-3.02.ebuild. В bash, команда "source" считывает все инструкции из указанного файла, и выполняет их как если бы они сразу находились в файле, содержащем команду "source". Таким образом, "source ${1}" заставляет "ebuild" скрипт выполнить команды из файла sed-3.02.ebuild, которые определяют переменные $P и $A. Это изменение конструкции очень удобно, потому что если мы захотим собрать другую программу вместо sed, мы можем просто создать новый .ebuild файл и передать его в качестве аргумента для нашего "ebuild" скрипта. Таким образом, .ebuild файлы становятся очень простыми, в то время как мозг системы ебилдов содержется в одном месте -- в нашем "ebuild" скрипте. Мы можем обновить или расширить систему ебилдов просто редактируя "ebuild" скрипт, сохраняя детали реализации за пределами ebuild файлов. Вот пример ebuild файла для gzip: neumann16 11.05.11 в 11:21 |
||
|
#другой действительно простой ebuild скрипт! neumann16 11.05.11 в 12:01 |
||
|
Добавление функциональности neumann16 11.05.11 в 12:01 |
||
|
ОК, мы добились некоторого прогресса. Однако, есть некоторая дополнительная функциональность которую я бы хотел добавить. Я хочу чтобы ebuild скрипт принимал второй аргумент командной строки, который будет принимать значение compile, unpack или all. Этот второй аргумент сообщает ebuild скрипту какой шаг необходимо выполнить. Таким образом, я могу сказать ebuild скрипту разархивировать архив, но не компилировать его (на всякий случай мне нужно проверить исходный архив перед компиляцией). Для этого, я добавлю оператор case который будет проверять переменную $2, и делать различные вещи, основываясь на ее значении. Вот этот код: neumann16 11.05.11 в 12:39 |
||
|
#!/usr/bin/env bash neumann16 11.05.11 в 13:48 |
||
|
Мы сделали много изменений, поэтому давайте рассмотрим их. Во-первых, мы разместили шаги компиляции и распаковки в их собственные функции, и назвали их ebuild_compile () и ebuild_unpack (), соответственно. Это хороший шаг, так как код становится более сложным, и новые функции предоставляют некоторую модульность, которая помогает держать код более организовано. В первой строке каждой функции, я явно выполняю cd в нужный каталог, так как хочу быть увереным, потому что наш код становится более модульным, а не линейным, поэтому вероятно, что мы можем ошибиться и выполнить функцию в неправильном рабочем каталоге. Команды cd явно переносят нас в нужное место, и не дает нам сделать ошибку позже - это важный шаг - особенно, если вы будете удалять файлы внутри функции. neumann16 12.05.11 в 06:04 |
||
|
Кроме того, я добавил полезную проверку в начало функции ebuild_compile(). Теперь, проверяется, что переменная $SRCDIR существует, и если ее нет, то появляется сообщение об ошибке, говорящее пользователю о необходимости вначале распаковать архив, а затем происходит выход. Если вы хотите, вы можете изменить это поведение так, что если $SRCDIR не существует, наши ebuild скрипты будут распаковать исходный архив автоматически. Вы можете сделать это, заменив функцию ebuild_compile () следующим кодом: neumann16 12.05.11 в 06:09 |
||
|
ebuild_compile() { bugzy 01.03.11 в 14:26 ebuild_compile() { neumann16 12.05.11 в 06:12 |
||
|
Одно из наиболее очевидных изменений в нашей второй версии ebuild скрипта это новый оператор case в конце кода. Этот оператор case просто проверяет второй аргумент командной строки и выполняет правильное действие, в зависимости от его значения. Если мы теперь введем: neumann16 12.05.11 в 06:14 |
||
|
$ ebuild sed-3.02.ebuild Daemon786 24.01.11 в 13:21 |
||
|
Мы действительно получим сообщение об ошибке. Ebuild теперь хочет чтобы ему сообщали, что ему делать: neumann16 12.05.11 в 06:17 |
||
|
$ ebuild sed-3.02.ebuild unpack Daemon786 24.01.11 в 13:22 |
||
|
или: Daemon786 24.01.11 в 13:22 |
||
|
$ ebuild sed-3.02.ebuild compile Daemon786 24.01.11 в 13:22 |
||
|
или: Daemon786 24.01.11 в 13:23 |
||
|
$ ebuild sed-3.02.ebuild all Daemon786 24.01.11 в 13:23 |
||
|
Важно! neumann16 12.05.11 в 06:23 |
||
