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 | 173 |
1 files changed, 136 insertions, 37 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 index 59e22915d2..a71f5e642d 100644 --- a/documentation/content/ru/books/porters-handbook/slow-porting/_index.adoc +++ b/documentation/content/ru/books/porters-handbook/slow-porting/_index.adoc @@ -1,11 +1,13 @@ --- -title: Глава 4. Медленное портирование -prev: books/porters-handbook/quick-porting +description: 'Описание создания порта FreeBSD, когда программа требует некоторых изменений' next: books/porters-handbook/makefiles +params: + path: /books/porters-handbook/slow-porting/ +prev: books/porters-handbook/quick-porting showBookMenu: true +tags: ["porting", "ports", "slow porting", "guide"] +title: 'Глава 4. Медленное портирование' weight: 4 -params: - path: "/books/porters-handbook/slow-porting/" --- [[slow-porting]] @@ -51,23 +53,22 @@ endif::[] [[slow-work]] == Как всё это работает -Во-первых, когда пользователь дает в своем каталоге с портом команду `make`, происходит целая череда событий. Во время чтения этого текста может оказаться полезным иметь файл [.filename]#bsd.port.mk# открытым в другом окне, что сильно поможет в их понимании. +Во-первых, когда пользователь дает в своем каталоге с портом команду `make`, происходит целая череда событий. Во время чтения этого текста может оказаться полезным иметь файл [.filename]#bsd.port.mk# открытым в другом окне, что сильно поможет его понять. -Но не волнуйтесь сильно, если вы не до конца понимаете, что делается в [.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#. +.. Если он существует, запускается [.filename]#scripts/configure#. +.. Если установлены `HAS_CONFIGURE` или `GNU_CONFIGURE`, запускается [.filename]#WRKSRC/configure#. . Выполняется цель `build`. Она отвечает за переход в собственный рабочий каталог порта (`WRKSRC`) и его построение. . Выполняется цель `stage`. Конечный набор построенных файлов помещается во временный каталог (`STAGEDIR`, смотрите crossref:special[staging,Staging]). Иерархия этого каталога отражает иерархию каталогов системы, в которую данный пакет будет устанавливаться. -. Выполняется цель `install`. В систему копируются файлы, перечисленные в pkg-plist порта. -==== +. Выполняется цель `package`. При этом создается пакет с использованием файлов из временного каталога, созданного во время выполнения цели `stage`, и файла [.filename]#pkg-plist# порта. +. Выполняется цель `install`. Это устанавливает пакет, созданный во время цели `package`, в хост-систему. Выше перечислены стандартные действия. Кроме того, вы сами можете определить цели `pre-_что-то_` или `post-_что-то_`, или создать скрипты с такими именами в подкаталоге [.filename]#scripts#, и они будут запущены до или после выполнения действий по умолчанию. @@ -87,15 +88,15 @@ endif::[] Получите оригинальные исходные тексты (обычно) в виде упакованного tar-архива ([.filename]#foo.tar.gz# или [.filename]#foo.tar.bz2#) и скопируйте его в каталог `DISTDIR`. Всегда используйте исходные тексты _основной ветки разработки_ везде, где это возможно. -Вам потребуется задать значение переменной `MASTER_SITES` так, чтобы оно указывало на местоположение оригинального tar-архива. В файле [.filename]#bsd.sites.mk# вы найдёте краткие обозначения для большинства популярных сайтов. Пожалуйста, используйте эти сайты-и соответствующие определения-везде, где это возможно, чтобы избежать проблем повторения одной и той же информации в базе источников. Так как эти сайты со временем меняются, для всех причастных поддержка становится настоящим кошмаром. +Вам потребуется задать значение переменной `MASTER_SITES` так, чтобы оно указывало на местоположение оригинального tar-архива. В файле [.filename]#bsd.sites.mk# вы найдёте краткие обозначения для большинства популярных сайтов. Пожалуйста, используйте эти сайты-и соответствующие определения-везде, где это возможно, чтобы избежать проблем повторения одной и той же информации в базе источников. Так как эти сайты со временем меняются, для всех причастных поддержка становится настоящим кошмаром. Для подробностей смотрите crossref:makefiles[makefile-master_sites,`MASTER_SITES`]. Если вы не можете найти FTP/HTTP сайт с хорошим подключением к сети, или находите только сайты, которые имеют раздражающе нестандартные форматы, то можете захотеть поместить копию на надежный сервер FTP или HTTP, который вам доступен (например, ваша домашняя страница). -Если вы не можете найти доступного и надёжного места для помещения дистрибутивного файла, то мы сами сможем разместить его на сервере `ftp.FreeBSD.org`; однако это наименее рекомендуемое решение. Дистрибутивный файл должен быть помещён в каталог [.filename]#~/public_distfiles/# одного из пользователей машины `freefall`. Попросите того, кто коммиттил ваш порт, сделать это. Этот человек также задаст переменной `MASTER_SITES` значение `MASTER_SITE_LOCAL`, а в переменной `MASTER_SITE_SUBDIR` укажет своё имя пользователя с машины `freefall`. +Если вы не можете найти доступного и надёжного места для помещения дистрибутивного файла, то мы сами сможем разместить его на сервере `ftp.FreeBSD.org`; однако это наименее рекомендуемое решение. Дистрибутивный файл должен быть помещён в каталог [.filename]#~/public_distfiles/# одного из пользователей машины `freefall`. Попросите того, кто коммиттил ваш порт, сделать это. Этот человек также задаст переменной `MASTER_SITES` значение `MASTER_SITE_LOCAL`, а в переменной `MASTER_SITE_SUBDIR` укажет логин кластера FreeBSD. Если дистрибутивные файлы вашего порта постоянно меняются по неизвестным причинам без изменения версий со стороны автора, остаётся только поместить дистрибутив на вашу домашнюю Web-страницу и указать её первой в списке `MASTER_SITES`. Если можете, попытайтесь договориться с автором порта об этом; это действительно помогает в достижении некоторого управления исходным кодом. Размещение собственной версии поможет избежать появления ошибок у пользователей типа `checksum mismatch`, а также уменьшит нагрузку на людей, сопровождающих наш FTP-сервер. Также, если у порта имеется только один основной сервер, то рекомендуется поместить архивную копию на свой сайт и указать его в списке `MASTER_SITES` вторым. -Если вашему порту требуются дополнительные `патчи`, доступные в Интернет, скачайте также и их, поместив в каталог `DISTDIR`. Не волнуйтесь, если они находятся не на том же сайте, откуда взят дистрибутивный архив, мы умеем обрабатывать такие ситуации (смотрите описание <<porting-patchfiles,PATCHFILES>> ниже). +Если вашему порту требуются дополнительные `патчи`, доступные в Интернет, скачайте также и их, поместив в каталог `DISTDIR`. Не волнуйтесь, если они находятся не на том же сайте, откуда взят дистрибутивный архив, мы умеем обрабатывать такие ситуации (смотрите описание crossref:makefiles[porting-patchfiles,PATCHFILES] ниже). [[slow-modifying]] == Модификация порта @@ -110,61 +111,86 @@ endif::[] ==== [[slow-patch]] -== Создание патчей +== Работа с патчами Файлы, которые добавлялись или изменялись в процессе создания порта, могут быть выявлены программой man:diff[1], а результат работы этой программы может быть в дальнейшем передан программе man:patch[1]. Такое действие с обычным файлом подразумевает сохранение копии файла с первоначальным содержимым перед внесением каких-либо изменений. -[source,shell] +[source, shell] .... % cp file file.orig .... Патчи сохраняются в виде файлов с именем [.filename]#patch-*#, где _*_ обозначает путь к файлу, к которому применяется патч, такой как [.filename]#patch-Imakefile# или [.filename]#patch-src-config.h#. -После того как файл был изменён, используется man:diff[1] для получения разницы между первоначальной и изменённой версиями. Параметр `-u` указывает man:diff[1] выводить разницу в "унифицированном" формате, который также является предпочтительным. +[TIP] +==== +Используйте `BINARY_ALIAS` для замены жёстко заданных команд во время сборки и избежания исправлений в файлах сборки. Подробнее см. в crossref:makefiles[binary-alias,Использование `BINARY_ALIAS` для переименования команд вместо исправления сборки]. +==== + +[[slow-patch-rules]] +=== Общие правила для установки патчей -[source,shell] +Файлы патчей хранятся в `PATCHDIR`, обычно это [.filename]#files/#, откуда они будут автоматически применены. Все исправления должны быть относительны к `WRKSRC`. Обычно `WRKSRC` является подкаталогом `WRKDIR`, каталога, в котором распаковывается distfile. Используйте `make -V WRKSRC` для просмотра фактического пути. Имена файлов патчей должны соответствовать следующим правилам: + +* Избегайте ситуации, когда несколько патчей изменяют один и тот же файл. Например, если и [.filename]#patch-foobar.c#, и [.filename]#patch-foobar.c2# вносят изменения в [.filename]#${WRKSRC}/foobar.c#, это делает их хрупкими и затрудняет отладку. +* При создании имен для файлов исправлений заменяйте каждое подчеркивание (`\_`) на два подчеркивания (`\__`) и каждый слэш (`/`) на одно подчеркивание (`_`). Например, чтобы исправить файл с именем [.filename]#src/freeglut_joystick.c#, назовите соответствующий исправление [.filename]#patch-src_freeglut__joystick.c#. Не называйте исправления как [.filename]#patch-aa# или [.filename]#patch-ab#. Всегда используйте путь и имя файла в названиях исправлений. Использование `make makepatch` автоматически генерирует правильные имена. +* Патч может изменять несколько файлов, если изменения связаны между собой и патч назван соответствующим образом. Например, [.filename]#patch-add-missing-stdlib.h#. +* Используйте только символы `[-+.\_a-zA-Z0-9]` для именования патчей. В частности, __не используйте `::` как разделитель путей,__ вместо этого используйте `_`. + +Минимизируйте количество нефункциональных изменений пробелов в патчах. В мире открытого исходного кода распространена практика, когда проекты используют обширные части кодовой базы, но следуют разным правилам стиля и отступов. При переносе работоспособного функционала из одного проекта для исправления аналогичных участков в другом будьте внимательны: итоговый патч может быть переполнен нефункциональными изменениями. Это не только увеличивает размер репозитория портов, но и затрудняет понимание того, что именно вызвало проблему и какие изменения были внесены. + +Если файл необходимо удалить, сделайте это в цели `post-extract`, а не как часть исправления. + +[[slow-patch-manual]] +=== Ручное создание патчей + +[NOTE] +==== +Ручное создание патчей обычно не требуется. Предпочтительным методом является автоматическая генерация патчей, как описано ранее в этом разделе. Однако иногда может потребоваться ручное исправление. +==== + +Патчи сохраняются в файлы с именами [.filename]#patch-*#, где * указывает на путь к файлу, который патчится, например [.filename]#patch-Imakefile# или [.filename]#patch-src-config.h#. Патчи с именами файлов, не начинающимися с [.filename]#patch-#, не будут применены автоматически. + +После изменения файла используется man:diff[1] для записи различий между оригинальной и изменённой версиями. `-u` заставляет man:diff[1] выводить различия файлов в "унифицированном" формате (unified diffs), которые являются предпочтительным форматом. + +[source, shell] .... % diff -u file.orig file > patch-pathname-file .... Для порождении патчей для новых добавляемых файлов используется параметр `-N`, который заставляет man:diff[1] трактовать несуществующие прежде файлы как если бы они существовали, но имели пустое содержимое: -[source,shell] +[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, но также усложняет поиск того, что конкретно вызвало проблему и что вообще поменялось. +Использование опции рекурсии (`-r`) в man:diff[1] для создания патчей допустимо, но пожалуйста, проверяйте полученные патчи, чтобы убедиться в отсутствии ненужных данных. В частности, различия между резервными файлами, [.filename]##Makefile##, когда порт использует `Imake` или GNU `configure`, и т.д., являются избыточными и должны быть удалены. Если потребовалось отредактировать [.filename]#configure.in# и запустить `autoconf` для перегенерации `configure`, не включайте различия в `configure` (его объем часто достигает нескольких тысяч строк!). Вместо этого определите `USES=autoreconf` и возьмите различия для [.filename]#configure.in#. -Если нужно удалить файл, сделайте это при выполнении цели `post-extract`, вместо того чтобы оформлять это как часть патча. +[[slow-patch-automatic-replacements]] +=== Простая автоматическая замена -Простые перемещения могут быть выполнены непосредственно из [.filename]#Makefile# порта с использованием man:sed[1] в режиме in-place. Это удобно, когда при изменении используется значение переменной: +Простые замены могут быть выполнены напрямую из [.filename]#Makefile# порта, используя режим редактирования на месте утилиты man:sed[1]. Это полезно, когда изменения используют значение переменной: [.programlisting] .... post-patch: - @${REINPLACE_CMD} -e 's|for Linux|for FreeBSD|g' ${WRKSRC}/README + @${REINPLACE_CMD} -e 's|/usr/local|${PREFIX}|g' ${WRKSRC}/Makefile .... -Довольно часто в исходных файлах портируемого программного обеспечения используется конвенция CR/LF. Это может стать причиной проблем с дальнейшей упаковкой, предупреждениями компилятора или выполнением скриптов (таких как `/bin/sh^M not found`). Для быстрого преобразования всех файлов из CR/LF просто в LF добавьте в [.filename]#Makefile# порта эту запись: +[IMPORTANT] +==== +Используйте man:sed[1] только для замены изменяемого содержимого. Для замены статического содержимого необходимо использовать файлы исправлений вместо man:sed[1]. +==== + +Довольно часто портируемое программное обеспечение использует соглашение CR/LF в исходных файлах. Это может вызвать проблемы с дальнейшим наложением патчей, предупреждениями компилятора или выполнением скриптов (например, `/bin/sh^M не найден`). Для быстрого преобразования всех файлов из CR/LF в просто LF добавьте следующую запись в [.filename]#Makefile# порта: [.programlisting] .... USES= dos2unix .... -Может быть задан точный список преобразуемых файлов: +Список конкретных файлов для преобразования может быть указан: [.programlisting] .... @@ -172,7 +198,7 @@ USES= dos2unix DOS2UNIX_FILES= util.c util.h .... -Используйте `DOS2UNIX_REGEX`, чтобы преобразовать группу файлов в разных подкаталогах. Его параметром является регулярное выражение, совместимое с man:find[1]. Подробнее о формате в man:re_format[7]. Такой вариант удобен для преобразования всех файлов заданного расширения. Для примера, преобразуем все исходные файлы, не затрагивая двоичные файлы: +Используйте `DOS2UNIX_REGEX` для преобразования группы файлов во вложенных каталогах. Его аргумент — это совместимое с man:find[1] регулярное выражение. Подробнее о формате можно узнать в man:re_format[7]. Эта опция полезна для преобразования всех файлов с заданным расширением. Например, преобразовать все исходные файлы кода, оставив двоичные файлы без изменений: [.programlisting] .... @@ -180,7 +206,7 @@ USES= dos2unix DOS2UNIX_REGEX= .*\.([ch]|cpp) .... -Другим вариантом является использование `DOS2UNIX_GLOB`, который вызывает `find` для каждого из перечисленных в нём элементов. +Аналогичной опцией является `DOS2UNIX_GLOB`, которая запускает `find` для каждого указанного в ней элемента. [.programlisting] .... @@ -188,6 +214,79 @@ USES= dos2unix DOS2UNIX_GLOB= *.c *.cpp *.h .... +Базовый каталог для преобразования может быть установлен. Это полезно, когда имеется несколько distfiles и в нескольких из них содержатся файлы, требующие преобразования окончаний строк. + +[.programlisting] +.... +USES= dos2unix +DOS2UNIX_WRKSRC= ${WRKDIR} +.... + +[[slow-patch-extra]] +=== Внесение исправлений при условии + +Некоторые порты требуют патчей, которые применяются только для определённых версий FreeBSD или при включении или отключении конкретной опции. Условные патчи указываются путём размещения полных путей к файлам патчей в `EXTRA_PATCHES`. Имена файлов условных патчей обычно начинаются с [.filename]#extra-#, хотя это и не обязательно. Однако их имена _не должны_ начинаться с [.filename]#patch-#. Если это произойдёт, они будут применены безусловно фреймворком, что нежелательно для условных патчей. + +[[slow-patch-extra-ex1]] +.Применение патча для конкретной версии FreeBSD +[example] +==== +[.programlisting] +.... +.include <bsd.port.options.mk> + +# Patch in the iconv const qualifier before this +.if ${OPSYS} == FreeBSD && ${OSVERSION} < 1100069 +EXTRA_PATCHES= ${PATCHDIR}/extra-patch-fbsd10 +.endif + +.include <bsd.port.mk> +.... + +==== + +[[slow-patch-extra-ex2]] +.Опциональное применение патча +[example] +==== +Когда для crossref:makefiles[makefile-options,опции] требуется патч, используйте ``opt_EXTRA_PATCHES`` и ``opt_EXTRA_PATCHES_OFF``, чтобы сделать исправление зависимым от опции `opt`. Дополнительные сведения см. в crossref:makefiles[options-variables,Generic Variables Replacement, `OPT_VARIABLE` и `OPT_VARIABLE_OFF`]. + +[.programlisting] +.... +OPTIONS_DEFINE= FOO BAR +FOO_EXTRA_PATCHES= ${PATCHDIR}/extra-patch-foo +BAR_EXTRA_PATCHES_OFF= ${PATCHDIR}/extra-patch-bar.c \ + ${PATCHDIR}/extra-patch-bar.h +.... + +==== + +[[slow-patch-extra-ex-dirs]] +.Использование `EXTRA_PATCHES` с директорией +[example] +==== +Иногда для функции требуется множество патчей, в таком случае можно указать `EXTRA_PATCHES` на директорию, и все файлы с именем [.filename]#patch-*# в ней будут применены автоматически. + +Создайте подкаталог в [.filename]#${PATCHDIR}# и переместите в него патчи. Например: + +[source, shell] +.... +% ls -l files/foo-patches +-rw-r--r-- 1 root wheel 350 Jan 16 01:27 patch-Makefile.in +-rw-r--r-- 1 root wheel 3084 Jan 18 15:37 patch-configure.ac +.... + +Затем добавьте это в [.filename]#Makefile#: + +[.programlisting] +.... +OPTIONS_DEFINE= FOO +FOO_EXTRA_PATCHES= ${PATCHDIR}/foo-patches +.... + +Затем фреймворк использует все файлы с именем [.filename]#patch-*# в этом каталоге. +==== + [[slow-configure]] == Конфигурирование |