diff options
Diffstat (limited to 'documentation/content/ru/books/porters-handbook/slow-porting/_index.adoc')
-rw-r--r-- | documentation/content/ru/books/porters-handbook/slow-porting/_index.adoc | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/documentation/content/ru/books/porters-handbook/slow-porting/_index.adoc b/documentation/content/ru/books/porters-handbook/slow-porting/_index.adoc new file mode 100644 index 0000000000..48af78675d --- /dev/null +++ b/documentation/content/ru/books/porters-handbook/slow-porting/_index.adoc @@ -0,0 +1,200 @@ +--- +title: Глава 4. Медленное портирование +prev: books/porters-handbook/quick-porting +next: books/porters-handbook/makefiles +showBookMenu: true +weight: 4 +path: "/books/porters-handbook/slow-porting/" +--- + +[[slow-porting]] += Медленное портирование +:doctype: book +:toc: macro +:toclevels: 1 +:icons: font +:sectnums: +:sectnumlevels: 6 +:sectnumoffset: 4 +:partnums: +:source-highlighter: rouge +:experimental: +:images-path: books/porters-handbook/ + +ifdef::env-beastie[] +ifdef::backend-html5[] +:imagesdir: ../../../../images/{images-path} +endif::[] +ifndef::book[] +include::shared/authors.adoc[] +include::shared/mirrors.adoc[] +include::shared/releases.adoc[] +include::shared/attributes/attributes-{{% lang %}}.adoc[] +include::shared/{{% lang %}}/teams.adoc[] +include::shared/{{% lang %}}/mailing-lists.adoc[] +include::shared/{{% lang %}}/urls.adoc[] +toc::[] +endif::[] +ifdef::backend-pdf,backend-epub3[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] +endif::[] + +ifndef::env-beastie[] +toc::[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] + +Итак, все оказалось не так уж и просто, и порт потребовал некоторых модификаций для того, чтобы заставить его работать. В этом разделе мы расскажем, шаг за шагом, как его модифицировать, чтобы он работал с нашей системой портов. + +[[slow-work]] +== Как всё это работает + +Во-первых, когда пользователь дает в своем каталоге с портом команду `make`, происходит целая череда событий. Во время чтения этого текста может оказаться полезным иметь файл [.filename]#bsd.port.mk# открытым в другом окне, что сильно поможет в их понимании. + +Но не волнуйтесь сильно, если вы не до конца понимаете, что делается в [.filename]#bsd.port.mk#, не так уж много людей его понимает... _:->_ + +[.procedure] +==== +. Запускается цель `fetch`. Цель `fetch` отвечает за то, что архив исходных текстов имеется в наличии локально в каталоге `DISTDIR`. Если цель `fetch` не может найти требуемые файлы в каталоге `DISTDIR`, то они будут искаться по указателю URL `MASTER_SITES`, который устанавливается в Makefile, а также на наших FTP зеркалах, куда мы по возможности помещаем дистрибутивные файлы для архива. Затем она попытается сгрузить указанный файл с помощью `FETCH`, полагая, что запрашивающая машина имеет прямое подключение к Интернет. Если файл скачается удачно, то он будет помещен в каталог `DISTDIR` для последующего использования и обработки. +. Выполняется цель `extract`. Она ищет дистрибутивный файл порта (как правило, tar-архив `gzip`) в каталоге `DISTDIR` и распаковывает его во временный каталог, задаваемый переменной `WRKDIR` (по умолчанию [.filename]#work#). +. Выполняется цель `patch`. Во-первых, применяются все патчи, заданные переменной `PATCHFILES`. Во-вторых, если какие-либо файлы с патчами, носящие имена [.filename]#patch-*#, имеются в подкаталоге `PATCHDIR` (по умолчанию это каталог [.filename]#files#), то они применяются в этот момент в алфавитном порядке. +. Запускается цель `configure`. Здесь может выполняться любая из многих различных вещей. +.. Если существует скрипт [.filename]#scripts/configure#, то он запускается. +.. Если задана переменная `HAS_CONFIGURE` или `GNU_CONFIGURE`, то запускается скрипт [.filename]#WRKSRC/configure#. + +. Выполняется цель `build`. Она отвечает за переход в собственный рабочий каталог порта (`WRKSRC`) и его построение. +. Выполняется цель `stage`. Конечный набор построенных файлов помещается во временный каталог (`STAGEDIR`, смотрите crossref:special[staging,Staging]). Иерархия этого каталога отражает иерархию каталогов системы, в которую данный пакет будет устанавливаться. +. Выполняется цель `install`. В систему копируются файлы, перечисленные в pkg-plist порта. +==== + +Выше перечислены стандартные действия. Кроме того, вы сами можете определить цели `pre-_что-то_` или `post-_что-то_`, или создать скрипты с такими именами в подкаталоге [.filename]#scripts#, и они будут запущены до или после выполнения действий по умолчанию. + +Например, если у вас есть цель `post-extract`, определённая в вашем файле [.filename]#Makefile# и файл [.filename]#pre-build# в подкаталоге [.filename]#scripts#, то после выполнения обычных действий по распаковке, будет вызвана цель `post-extract` а скрипт [.filename]#pre-build# будет выполнен перед запуском стандартных правил построения. Рекомендуется использовать цели из [.filename]#Makefile#, если действия достаточно просты, потому что в дальнейшем будет проще определить, какие нестандартные действия требует порт. + +Действия по умолчанию выполняются целями `do-_что-то_` из [.filename]#bsd.port.mk#. Например, команды для распаковки порта находятся в цели `do-extract`. Если вам не хватает цели по умолчанию, вы можете ее исправить, переопределив цель `do-_something_` в вашем файле [.filename]#Makefile#. + +[NOTE] +==== +"Основные" цели (к примеру, `extract`, `configure` и так далее) не делают ничего больше, чем проверяют успешность завершения всех предыдущих шагов и вызывают настоящие цели или скрипты, и их не нужно менять. Если вам нужно изменить распаковку, исправляйте `do-extract`, но никогда не меняйте способ работы `extract`! Кроме того, цель `post-deinstall` является недействительной и не выполняется инфраструктурой портов. +==== + +Теперь, когда вы представляете, что происходит, когда пользователь набирает команду `make install`, давайте пройдемся через шаги, рекомендуемые для создания настоящего порта. + +[[slow-sources]] +== Получение исходного кода + +Получите оригинальные исходные тексты (обычно) в виде упакованного tar-архива ([.filename]#foo.tar.gz# или [.filename]#foo.tar.bz2#) и скопируйте его в каталог `DISTDIR`. Всегда используйте исходные тексты _основной ветки разработки_ везде, где это возможно. + +Вам потребуется задать значение переменной `MASTER_SITES` так, чтобы оно указывало на местоположение оригинального tar-архива. В файле [.filename]#bsd.sites.mk# вы найдёте краткие обозначения для большинства популярных сайтов. Пожалуйста, используйте эти сайты-и соответствующие определения-везде, где это возможно, чтобы избежать проблем повторения одной и той же информации в базе источников. Так как эти сайты со временем меняются, для всех причастных поддержка становится настоящим кошмаром. + +Если вы не можете найти FTP/HTTP сайт с хорошим подключением к сети, или находите только сайты, которые имеют раздражающе нестандартные форматы, то можете захотеть поместить копию на надежный сервер FTP или HTTP, который вам доступен (например, ваша домашняя страница). + +Если вы не можете найти доступного и надёжного места для помещения дистрибутивного файла, то мы сами сможем разместить его на сервере `ftp.FreeBSD.org`; однако это наименее рекомендуемое решение. Дистрибутивный файл должен быть помещён в каталог [.filename]#~/public_distfiles/# одного из пользователей машины `freefall`. Попросите того, кто коммиттил ваш порт, сделать это. Этот человек также задаст переменной `MASTER_SITES` значение `MASTER_SITE_LOCAL`, а в переменной `MASTER_SITE_SUBDIR` укажет своё имя пользователя с машины `freefall`. + +Если дистрибутивные файлы вашего порта постоянно меняются по неизвестным причинам без изменения версий со стороны автора, остаётся только поместить дистрибутив на вашу домашнюю Web-страницу и указать её первой в списке `MASTER_SITES`. Если можете, попытайтесь договориться с автором порта об этом; это действительно помогает в достижении некоторого управления исходным кодом. Размещение собственной версии поможет избежать появления ошибок у пользователей типа `checksum mismatch`, а также уменьшит нагрузку на людей, сопровождающих наш FTP-сервер. Также, если у порта имеется только один основной сервер, то рекомендуется поместить архивную копию на свой сайт и указать его в списке `MASTER_SITES` вторым. + +Если вашему порту требуются дополнительные `патчи`, доступные в Интернет, скачайте также и их, поместив в каталог `DISTDIR`. Не волнуйтесь, если они находятся не на том же сайте, откуда взят дистрибутивный архив, мы умеем обрабатывать такие ситуации (смотрите описание <<porting-patchfiles,PATCHFILES>> ниже). + +[[slow-modifying]] +== Модификация порта + +Распакуйте копию дистрибутивного файла в отдельный каталог и внесите изменения, которые необходимы для того, чтобы порт компилировался нормально в текущей версии FreeBSD. _Тщательно отслеживайте_ все, что вы делаете, этот процесс вам предстоит автоматизировать. Все, включая удаление, добавление или модификацию в файлах должны будут выполняться автоматически с помощью скриптов или файлов патчей, когда вы завершите работу над портом. + +Если вашему порту во время компиляции, установки и настройки требуется довольно много взаимодействовать с пользователем, то посмотрите на один из классических скриптов Configure Лэрри Уолла (Larry Wall) и сделайте сами что-либо подобное. Предназначение новой коллекции портов - это сделать каждое приложение в стиле "plug-and-play" настолько, насколько это вообще возможно для конечного пользователя при минимальном использовании дискового пространства. + +[NOTE] +==== +Если явно не указано обратное, то патчи, скрипты и другие файлы, которые вы создали и предоставили для Коллекции Портов FreeBSD, неявно подпадают под стандартные условия лицензии BSD. +==== + +[[slow-patch]] +== Создание патчей + +Файлы, которые добавлялись или изменялись в процессе создания порта, могут быть выявлены программой man:diff[1], а результат работы этой программы может быть в дальнейшем передан программе man:patch[1]. Такое действие с обычным файлом подразумевает сохранение копии файла с первоначальным содержимым перед внесением каких-либо изменений. + +[source,shell] +.... +% cp file file.orig +.... + +Патчи сохраняются в виде файлов с именем [.filename]#patch-*#, где _*_ обозначает путь к файлу, к которому применяется патч, такой как [.filename]#patch-Imakefile# или [.filename]#patch-src-config.h#. + +После того как файл был изменён, используется man:diff[1] для получения разницы между первоначальной и изменённой версиями. Параметр `-u` указывает man:diff[1] выводить разницу в "унифицированном" формате, который также является предпочтительным. + +[source,shell] +.... +% diff -u file.orig file > patch-pathname-file +.... + +Для порождении патчей для новых добавляемых файлов используется параметр `-N`, который заставляет man:diff[1] трактовать несуществующие прежде файлы как если бы они существовали, но имели пустое содержимое: + +[source,shell] +.... +% diff -u -N newfile.orig newfile > patch-pathname-newfile +.... + +Файлы с патчами помещаются в каталоге `PATCHDIR` (как правило, это [.filename]#files/#), откуда они будут взяты автоматически. Все патчи обязаны быть сделаны относительно каталога `WRKSRC` (как правило, это каталог, в который распаковывается исходный архив и где будет выполняться построение). Для упрощения внесения изменений и обновлений избегайте наличия более чем одного патча для одного и того же файла (например, патчей [.filename]#patch-file# и [.filename]#patch-file2#, оба меняющих файл [.filename]#WRKSRC/foobar.c#). Обратите внимание, что если путь к изменяемому файлу содержит символ подчеркивания (`_`), то патч должен содержать в своем имени два подчеркивания вместо одного. Например, для применения патча на файл с именем [.filename]#src/freeglut_joystick.c# соответствующий патч следует назвать [.filename]#patch-src-freeglut__joystick.c#. + +Пожалуйста, используйте для именования патчей только символы `[-+._a-zA-Z0-9]`. Не используйте любые другие символы, кроме этих. Не называйте патчи как [.filename]#patch-aa# или [.filename]#patch-ab#, всегда ссылайтесь на путь и название файла в названиях самих патчей. + +Существует альтернативный упрощённый способ создания патчей для существующих файлов. Первые шаги те же самые: создание копии неизменённого файла с расширением [.filename]#.orig# и внесение изменений. После этого используйте `make makepatch`, чтобы обновить файлы с патчами в каталоге [.filename]#files# данного порта. + +Не помещайте строки RCS в патчи. Subversion будет изменять их при помещении файлов в дерево портов, и когда мы будем их оттуда извлекать, они будут уже другие, поэтому применение патчей окончится неудачей. Строчки RCS предваряются знаком доллара (`$`), и обычно начинаются с `$Id` или `$RCS`. + +Использование параметра рекурсии (`-r`) с командой man:diff[1] для генерации патчей - это хорошо, но всё же, пожалуйста, смотрите на получающиеся патчи, чтобы убедиться в отсутствии ненужного мусора. В частности, diff-разниц между двумя резервными копиями файлов, файлы [.filename]#Makefile#, когда как порт использует `Imake` или GNU-версию программы `configure`, и так далее, не нужны, и должны быть удалены. Если было необходимо отредактировать файл [.filename]#configure.in# и запустить `autoconf` для перегенерации `configure`, не нужно включать файлы diff для `configure` (они частенько вырастают до нескольких тысяч строк!). Вместо этого задайте `USE_AUTOTOOLS=autoconf:261` и включите diff-файл для [.filename]#configure.in#. + +Старайтесь минимизировать в патчах объём нефункциональных изменений с пустыми символами. В мире Открытого Исходного Кода является распространенным совместное использование проектами больших объемов кодовой базы, но с различными стилями и правилами отступов. При копировании работающей функциональной части из одного проекта для исправления похожей области в другом, будьте аккуратны, пожалуйста: получаемый однострочный патч может указаться полон нефункциональных изменений. Это не только увеличивает размер репозитория Subversion, но также усложняет поиск того, что конкретно вызвало проблему и что вообще поменялось. + +Если нужно удалить файл, сделайте это при выполнении цели `post-extract`, вместо того чтобы оформлять это как часть патча. + +Простые перемещения могут быть выполнены непосредственно из [.filename]#Makefile# порта с использованием man:sed[1] в режиме in-place. Это удобно, когда при изменении используется значение переменной: + +[.programlisting] +.... +post-patch: + @${REINPLACE_CMD} -e 's|for Linux|for FreeBSD|g' ${WRKSRC}/README +.... + +Довольно часто в исходных файлах портируемого программного обеспечения используется конвенция CR/LF. Это может стать причиной проблем с дальнейшей упаковкой, предупреждениями компилятора или выполнением скриптов (таких как `/bin/sh^M not found`). Для быстрого преобразования всех файлов из CR/LF просто в LF добавьте в [.filename]#Makefile# порта эту запись: + +[.programlisting] +.... +USES= dos2unix +.... + +Может быть задан точный список преобразуемых файлов: + +[.programlisting] +.... +USES= dos2unix +DOS2UNIX_FILES= util.c util.h +.... + +Используйте `DOS2UNIX_REGEX`, чтобы преобразовать группу файлов в разных подкаталогах. Его параметром является регулярное выражение, совместимое с man:find[1]. Подробнее о формате в man:re_format[7]. Такой вариант удобен для преобразования всех файлов заданного расширения. Для примера, преобразуем все исходные файлы, не затрагивая двоичные файлы: + +[.programlisting] +.... +USES= dos2unix +DOS2UNIX_REGEX= .*\.([ch]|cpp) +.... + +Другим вариантом является использование `DOS2UNIX_GLOB`, который вызывает `find` для каждого из перечисленных в нём элементов. + +[.programlisting] +.... +USES= dos2unix +DOS2UNIX_GLOB= *.c *.cpp *.h +.... + +[[slow-configure]] +== Конфигурирование + +Поместите все дополнительные команды, требуемые для настройки, в ваш скрипт [.filename]#configure# и сохраните его в подкаталоге [.filename]#scripts#. Как отмечено выше, вы можете сделать это целями в файле [.filename]#Makefile# и/или скриптами с именами [.filename]#pre-configure# или [.filename]#post-configure#. + +[[slow-user-input]] +== Обработка пользовательского ввода + +Если для построения, конфигурации или установки вашего порта требуется некоторый ввод со стороны пользователя, то вы должны задать переменную `IS_INTERACTIVE` в вашем файле [.filename]#Makefile#. В случае "ночного построения" это позволит пропустить ваш порт, если пользователь в своем окружении задал переменную `BATCH` (и если пользователь установил переменную `INTERACTIVE`, то будут строиться _только_ порты, которые требуют взаимодействия с пользователем. Это сэкономит значительное количество времени на части машин, которые постоянно строят порты (смотрите ниже). + +При наличии разумных ответов на задаваемые вопросы, подходящих по умолчанию, также рекомендуется проверять переменную `PACKAGE_BUILDING` и выключать интерактивный скрипт, если он есть. Это позволит нам строить пакеты для помещения на компакт-диски и FTP-серверы. |