<!--
     The FreeBSD Russian Documentation Project

     $FreeBSD: doc/ru_RU.KOI8-R/books/porters-handbook/book.sgml,v 1.9 2002/01/12 14:31:41 phantom Exp $
     $FreeBSDru: frdp/doc/ru_RU.KOI8-R/books/porters-handbook/book.sgml,v 1.75 2002/01/03 14:10:14 andy Exp $

     Original revision: 1.189
-->

<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
%man;
<!ENTITY % bookinfo PUBLIC "-//FreeBSD//ENTITIES DocBook BookInfo Entities//RU">
%bookinfo;
<!ENTITY % authors PUBLIC "-//FreeBSD//ENTITIES DocBook Author Entities//EN"> %authors;
<!ENTITY % mailing-lists PUBLIC "-//FreeBSD//ENTITIES DocBook Mailing List Entities//RU">
%mailing-lists;
]>

<book>
  <bookinfo>
    <title>Руководство FreeBSD по созданию портов</title>

    <authorgroup>
      <corpauthor>The FreeBSD Russian Documentation Project</corpauthor>
    </authorgroup>

    <pubdate>Апрель 2000</pubdate>

    <copyright>
      <year>2000</year>
      <year>2001</year>
      <year>2002</year>
      <holder role="mailto:doc@FreeBSD.org">
        The FreeBSD Documentation Project</holder>
    </copyright>

    &bookinfo.legalnotice;
  </bookinfo>

<chapter>
  <title>Как самому сделать порт</title>

  <para>Итак, теперь вас интересует, как создать собственный порт или
    обновить существующий?  Великолепно!</para>

  <para>Ниже находятся некоторые указания по созданию нового порта для
    FreeBSD.	Если вы хотите обновить существующий порт, вы должны
    прочесть их, а затем <xref linkend="port-upgrading">.</para>

  <para>Если этот документ недостаточно подробен, вы должны обратиться к
    файлу <filename>/usr/ports/Mk/bsd.port.mk</filename>, который
    включается в make-файл каждого порта.  Он хорошо прокомментирован, и
    даже если вы не занимаетесь хаканьем make-файлов каждодневно,  из него
    вы сможете узнать много нового.  Кроме того, конкретные вопросы можно
    задать, послав письмо на адрес &a.ports;.</para>

  <note>
    <para>Только часть переменных
      (<makevar><replaceable>VAR</replaceable></makevar>), которые могут
      быть переопределены, описаны в этом документе.  Большинство (если не
      все) описаны в начале файла <filename>bsd.port.mk</filename>.
      В этом файле используется нестандартная настройка шага табуляции.
      <application>Emacs</application> и <application>Vim</application>
      должны распознать это при загрузке файла.  Как <command>vi</command>,
      так и <command>ex</command> могут быть настроены на использование
      правильного значения выдачей команды <command>:set tabstop=4</command>
      после загрузки файла.</para>
  </note>
</chapter>

<chapter id="quick-porting">
  <title>Быстрое портирование</title>

  <para>В этом разделе будет описано, как сделать порт на скорую руку.
    Во многих случаях этого бывает недостаточно, но мы посмотрим.</para>

  <para>Во-первых, скачайте оригинальный tar-файл и поместите его в каталог
    <makevar>DISTDIR</makevar>, который по умолчанию есть не что иное, как
    <filename>/usr/ports/distfiles</filename>.</para>

  <note>
    <para>Здесь предполагается, что программное обеспечение компилируется
      без проблем как есть, то есть для работы приложения на вашей системе
      FreeBSD не потребовалось абсолютно никаких изменений.  Если
      требовалось что-то изменить, то вам придется обратиться также и к
      следующему разделу.</para>
  </note>

  <sect1>
    <title>Создание файла <filename>Makefile</filename></title>

    <para>Минимальный <filename>Makefile</filename> будет выглядеть
      примерно так:</para>

    <programlisting>
# New ports collection makefile for:   oneko
# Date created:        5 December 1994
# Whom: 	       asami
#
# &dollar;FreeBSD&dollar;
#

PORTNAME=      oneko
PORTVERSION=   1.1b
CATEGORIES=    games
MASTER_SITES=  ftp://ftp.cs.columbia.edu/archives/X11R5/contrib/

MAINTAINER=    asami@FreeBSD.org

MAN1=	       oneko.1
MANCOMPRESSED= yes
USE_IMAKE=     yes

.include &lt;bsd.port.mk&gt;
    </programlisting>

    <para>Посмотрим, сможете ли вы его понять.  Не обращайте внимание на
      содержимое строчки <literal>&dollar;FreeBSD&dollar;</literal>, она
      будет заполнена автоматически системой CVS, когда порт будет
      импортирован в наше дерево портов.  Вы можете найти более подробный
      пример в разделе <link linkend="porting-samplem">пример
      Makefile</link>.</para>
  </sect1>

  <sect1>
    <title>Создание информационных файлов</title>

    <para>Имеется три информационных файла, которые требуются для любого
      порта, вне зависимости от того, является ли он пакаджем или нет.  Это
      <filename>pkg-comment</filename>, <filename>pkg-descr</filename> и
      <filename>pkg-plist</filename>, и их префикс <filename>pkg-</filename>
      отличает их от других файлов.</para>

    <sect2>
      <title><filename>pkg-comment</filename></title>

      <para>Это однострочное описание порта.
        <emphasis>Пожалуйста</emphasis>, не включайте сюда название
        пакаджа (или номер версии программного обеспечения).
        Комментарий должен начинаться с заглавной буквы и не
        заканчиваться точкой.  Вот пример:</para>

      <programlisting>
A cat chasing a mouse all over the screen
      </programlisting>
    </sect2>

    <sect2>
      <title><filename>pkg-descr</filename></title>

      <para>Это более подробное краткое описание порта.  От одного до
        нескольких абзацев, кратко описывающих, что представляет собой
        порт, будет достаточно.</para>

      <note>
        <para>Это <emphasis>не</emphasis> руководство и не подробнейшее
          описание того, как использовать или компилировать порт!
          <emphasis>Пожалуйста, будьте внимательны при копировании текста
          из <filename>README</filename> или страниц
          справочника</emphasis>; слишком часто они не являются кратким
          описанием порта или имеют неудобный формат (например, страницы
	  справочника выровнены пробелами).  Если портируемое приложение
	  имеет официальную страничку Интернет, укажите ее здесь.
	  Предварите <emphasis>один</emphasis> из сайтов словом
	  <literal>WWW:</literal> для того, чтобы вспомогательные утилиты
	  работали правильно.</para>
      </note>

      <para>Рекомендуется, чтобы вы указали свое имя в конце этого файла,
        как здесь:</para>

      <programlisting>
This is a port of oneko, in which a cat chases a poor mouse all over
the screen.
 :
(etc.)

WWW: http://www.oneko.org/

- Satoshi
asami@cs.berkeley.edu
      </programlisting>
    </sect2>

    <sect2>
      <title><filename>pkg-plist</filename></title>

      <para>Здесь перечисляются все файлы, устанавливаемые портом.  Его
        также называют <quote>списком для упаковки</quote>, потому что
        пакадж генерируется упаковкой файлов, которые здесь указаны.
        Имена путей указываются относительно установочного префикса
        (обычно <filename>/usr/local</filename> или
        <filename>/usr/X11R6</filename>).  Если вы используете переменные
        <makevar>MAN<replaceable>n</replaceable></makevar> (а вы должны
        это делать), то указывать страницы справочника здесь не
        нужно.</para>

      <para>Вот маленький пример:</para>

      <programlisting>
bin/oneko
lib/X11/app-defaults/Oneko
lib/X11/oneko/cat1.xpm
lib/X11/oneko/cat2.xpm
lib/X11/oneko/mouse.xpm
@dirrm lib/X11/oneko
      </programlisting>

      <para>Обратитесь к странице Справочника по команде
        &man.pkg.create.1; с подробным описанием формата списка
        упаковки.</para>

      <note>
        <para>В списке вы должны указать все файлы, но не каталоги.
          Кроме того, если порт создает каталоги сам на этапе установки,
          нужно добавить директивы <literal>@dirrm</literal> в подходящие
          места для удаления их при удалении порта.</para>

        <para>Рекомендуется, чтобы имена файлов в этом списке были
	  отсортированы в алфавитном порядке.  Это позволит значительно
	  облегчить сверку изменений при обновлении порта.</para>

	<para>Создание списка упаковки вручную может оказаться весьма
	  трудоёмкой задачей.  Если порт устанавливает большое количество
	  файлов, раздел об <link
	  linkend="porting-autoplist">автоматическом построении списка
	  упаковки</link> может помочь сэкономить время.</para>
      </note>
    </sect2>
  </sect1>

  <sect1>
    <title>Создание файла с контрольной суммой</title>

    <para>Просто введите команду <command>make makesum</command>.
      Правила утилиты make автоматически сгенерируют файл
      <filename>distinfo</filename>.</para>
  </sect1>

    <sect1 id="porting-testing">
      <title>Тестирование порта</title>

      <para>Вы должны удостовериться, что правила построения порта выполняют
	именно то, что вы хотите, включая создание пакаджа для порта.  Вот
	те важные вещи, которые вы должны проверить.</para>

      <itemizedlist>
	<listitem>
	  <para><filename>pkg-plist</filename> не содержит ничего сверх того,
	    что устанавливается вашим портом</para>
	</listitem>

	<listitem>
	  <para><filename>pkg-plist</filename> содержит абсолютно все, что
	    устанавливается вашим портом</para>
	</listitem>

	<listitem>
	    <para>Ваш порт может быть переустановлен множество раз с помощью
	      указания цели <maketarget>reinstall</maketarget></para>
	</listitem>

	<listitem>
	  <para>Ваш порт <link linkend="porting-cleaning">подчищает</link>
	    за собой после своего удаления</para>
	</listitem>
      </itemizedlist>

      <procedure>
	<title>Рекомендуемый порядок проверки</title>

	<step>
	  <para><command>make install</command></para>
	</step>

	<step>
	  <para><command>make package</command></para>
	</step>

	<step>
	  <para><command>make deinstall</command></para>
	</step>

	<step>
	  <para><command>pkg_add <replaceable>package-name</replaceable>
	    </command></para>
	</step>

	<step>
	  <para><command>make deinstall</command></para>
	</step>

	<step>
	  <para><command>make reinstall</command></para>
	</step>

	<step>
	  <para><command>make package</command></para>
	</step>
      </procedure>

      <para>Проверьте, что ни на шаге <maketarget>package</maketarget>, ни на
	шаге <maketarget>deinstall</maketarget> не выдается никаких
	предупреждений.  После выполнения шага 3 проверьте, что все новые
	каталоги были успешно удалены.	Также попробуйте запустить
	программное обеспечение после выполнения шага 4, чтобы убедиться, что
	оно работает правильно при установке из пакаджа.</para>
    </sect1>

    <sect1 id="porting-portlint">
      <title>Проверка вашего порта утилитой
	<command>portlint</command></title>

      <para>Будьте добры, пользуйтесь утилитой <command>portlint</command>
	для проверки того, что ваш порт соответствует нашим рекомендациям.
	Программа <command>portlint</command> является частью Коллекции
	Портов.  В частности, вы можете захотеть проверить, правильно ли
	сформирован файл <link linkend="porting-samplem">Makefile</link> и
	соответствующим ли образом наименован <link
	linkend="porting-pkgname">пакадж</link>.</para>
    </sect1>

    <sect1 id="porting-submitting">
      <title>Посылка порта</title>

      <para>Первым делом удостоверьтесь, что вы прочитали раздел о
	том, что <link
	linkend="porting-dads">можно и нельзя</link> делать.</para>

      <para>Теперь, когда вы счастливы от своего первого порта, единственное,
	что осталось сделать, это включить его в основное дерево портов
	FreeBSD и осчастливить этим всех остальных.  Нам не нужен ни ваш
	каталог <filename>work</filename>, ни пакадж
	<filename>pkgname.tgz</filename>, так что удалите их прямо сейчас.
	Затем просто включите вывод команды
	<command>shar `find port_dir`</command> в сообщение об ошибке и пошлите
        его с помощью программы &man.send-pr.1; (обратитесь к разделу <ulink
        url="../../articles/contributing/handbook/contrib-how.html#CONTRIB-GENERAL">
        Сообщения об ошибках и общие замечания</ulink> для получения подробной
        информации о программе &man.send-pr.1;.  Если размер неупакованного
        порта превышает 20 КБ, то
        сожмите его в tar-файл и воспользуйтесь утилитой &man.uuencode.1; перед
        тем, как включить его в сообщение (можно посылать такие файлы, даже если
	сообщение не превышают 20КБ, но это не рекомендуется).	Не забудьте
	указать в сообщении категорию <literal>ports</literal> и класс
	<literal>change-request</literal> (Не указывайте, что сообщение
	имеет статус <literal>confidential</literal>!).  Добавьте также
        краткое описание программы, порт которой вы создали, в раздел
        <quote>Description</quote> отправляемого PR и сам порт в виде архива
        shar или архива tar, обработанного утилитой uuencode, поместив его в
        раздел <quote>Fix</quote>.  Последнее облегчит труд коммиттеров,
        которые используют скрипты для выполнения своей работы, связанной с
        портами.</para>

      <para>Повторим еще раз, что <emphasis>не нужно включать ни оригинальный
	файл с дистрибутивом, ни каталог <filename>work</filename>,
	ни пакадж, построенный вами командой
	<command>make package</command></emphasis>.</para>

      <note>
	<para>В прошлом мы просили вас закачивать новые порты на FTP-сервер
	  (<hostid role="fqdn">ftp.FreeBSD.org</hostid>).  Больше этого делать
          не нужно, так как на каталог <filename>incoming/</filename>
	  нет доступа в режиме чтения, из-за большого количества пиратского
	  программного обеспечения, оказавшегося в нем.</para>
      </note>

      <para>Мы посмотрим на ваш порт, при необходимости вернём его обратно, а
        затем включим порт в наше дерево.  Ваше имя также появится в списке
	<quote>Людей, внесших свой вклад</quote> в Руководстве и других
	файлах.  Это ли не круто?!? <!-- smiley -->:-)</para>

      <note>
        <para>Вы можете значительно облегчить нам работу, если будете давать
          хорошее описание в поле описания проблемы при посылке.  Мы
          предпочитаем нечто вроде <quote>New port: &lt;краткое описание
          порта&gt;</quote> в случае нового порта и <quote>Update port:
          &lt;category&gt;/&lt;port&gt; &lt;краткое описание
          обновлений&gt;</quote> в случае обновления порта.  Если вы будете
          придерживаться этой схемы, то шансы, что кто-нибудь вскоре взглянет
          на ваш PR, весьма высоки.</para>
      </note>
    </sect1>
  </chapter>

  <chapter>
    <title>Медленное портирование</title>

    <para>Итак, все оказалось не так уж и просто, и порт потребовал
      некоторых модификаций для того, чтобы заставить его работать.  В этом
      разделе мы расскажем, шаг за шагом, как его модифицировать, чтобы он
      работал с нашей системой портов.</para>

    <sect1>
      <title>Как всё это работает</title>

      <para>Во-первых, когда пользователь дает в своем каталоге с портом
	команду <command>make</command>, происходит целая череда событий.
	Во время чтения этого текста может оказаться полезным иметь файл
	<filename>bsd.port.mk</filename> открытым в другом окне, что сильно
	поможет в их понимании.</para>

      <para>Но не волнуйтесь сильно, если вы не до конца понимаете, что
	делается в <filename>bsd.port.mk</filename>, не так уж много людей
	его понимает... <!-- smiley --><emphasis>:-&gt;</emphasis></para>

      <procedure>
	<step>
	  <para>Запускается цель <maketarget>fetch</maketarget>.  Цель
	    <maketarget>fetch</maketarget> отвечает за то, что архив исходных
	    текстов имеется в наличии локально в каталоге
	    <makevar>DISTDIR</makevar>.  Если цель
	    <maketarget>fetch</maketarget> не может найти требуемые файлы в
	    каталоге <makevar>DISTDIR</makevar>, то он будет искаться по
	    указателю URL <makevar>MASTER_SITES</makevar>, который
	    устанавливается в Makefile, а также на нашем основном FTP-сервере
	    по адресу <ulink
	    url="ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/">
	    ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/</ulink>, куда
	    мы по возможности помещаем дистрибутивные файлы для архива.
	    Затем она попытается сгрузить указанный файл с помощью
	    <makevar>FETCH</makevar>, полагая, что запрашивающая машина имеет
	    прямое подключение к Интернет.  Если файл скачается удачно, то
	    он будет помещен в каталог <makevar>DISTDIR</makevar> для
	    последующего использования и обработки.</para>
	</step>

	<step>
	  <para>Выполняется цель <maketarget>extract</maketarget>.  Она ищет
	    дистрибутивный файл порта (как правило, tar-архив gzip) в
	    каталоге <makevar>DISTDIR</makevar> и распаковывает его во
	    временный каталог, задаваемый переменной
	    <makevar>WRKDIR</makevar> (по умолчанию
	    <filename>work</filename>).</para>
	</step>

	<step>
	  <para>Выполняется цель <maketarget>patch</maketarget>.  Во-первых,
	    применяются все патчи, заданные переменной
	    <makevar>PATCHFILES</makevar>.  Во-вторых, если какие-либо файлы с
            патчами, носящие имена
            <filename>patch-<replaceable>*</replaceable></filename>, имеются в
	    подкаталоге <makevar>PATCHDIR</makevar> (по умолчанию это каталог
            <filename>files</filename>), то они применяются в этот момент в
            алфавитном порядке.</para>
	</step>

	<step>
	  <para>Запускается цель <maketarget>configure</maketarget>.  Здесь
	    может выполняться любая из многих различных вещей.</para>

	  <orderedlist>
	    <listitem>
	      <para>Если существует скрипт
		<filename>scripts/configure</filename>, то он запускается.
	      </para>
	    </listitem>

	    <listitem>
	      <para>Если задана переменная <makevar>HAS_CONFIGURE</makevar>
		или <makevar>GNU_CONFIGURE</makevar>, то запускается скрипт
		<filename><makevar>WRKSRC</makevar>/configure</filename>.
	      </para>
	    </listitem>

	    <listitem>
	      <para>Если задана переменная <makevar>USE_IMAKE</makevar>,
		то запускается команда <makevar>XMKMF</makevar> (по умолчанию
		это <command>xmkmf -a</command>).</para>
	    </listitem>
	  </orderedlist>
	</step>

	<step>
	  <para>Выполняется цель <maketarget>build</maketarget>.  Она
	    отвечает за переход в собственный рабочий каталог порта
	    (<makevar>WRKSRC</makevar>) и его построение.  Если задана
	    переменная <makevar>USE_GMAKE</makevar>, будет использоваться
	    GNU-версия утилиты <command>make</command>, в противном случае
	    будет использована системная утилита
	    <command>make</command>.</para>
	</step>
      </procedure>

      <para>Выше перечислены стандартные действия.  Кроме того, вы сами
	можете определить цели
	<maketarget>pre-<replaceable>что-то</replaceable></maketarget> или
	<maketarget>post-<replaceable>что-то</replaceable></maketarget>,
	или создать скрипты с такими именами в подкаталоге
	<filename>scripts</filename>, и они будут запущены до или после
	выполнения действий по умолчанию.</para>

      <para>Например, если у вас есть цель
	<maketarget>post-extract</maketarget>, определенная в вашем файле
	Makefile и файл <filename>pre-build</filename> в подкаталоге
	<filename>scripts</filename>, то после выполнения обычных действий по
	распаковке, будет вызвана цель <maketarget>post-extract</maketarget>
	а скрипт <filename>pre-build</filename> будет выполнен перед
	запуском стандартных правил построения.  Рекомендуется использовать
	цели из <filename>Makefile</filename>, если действия достаточно
	просты, потому что в дальнейшем будет проще определить, какие
	нестандартные действия требует порт.</para>

      <para>Действия по умолчанию выполняются целями
	<maketarget>do-<replaceable>что-то</replaceable></maketarget> из
	<filename>bsd.port.mk</filename>.  Например, команды для
	распаковки порта находятся в цели
	<maketarget>do-extract</maketarget>.  Если вам не хватает цели по
	умолчанию, вы можете ее исправить, переопределив цель
	<maketarget>do-<replaceable>something</replaceable></maketarget>
	в вашем файле <filename>Makefile</filename>.</para>

      <note>
	<para><quote>Основные</quote> цели (к примеру,
	  <maketarget>extract</maketarget>,
	  <maketarget>configure</maketarget>, и тд.) не делают ничего больше,
	  чем проверяют успешность завершения всех предыдущих шагов и
	  вызывают настоящие цели или скрипты, и их не нужно менять.  Если
	  вам нужно изменить распаковку, исправляйте
	  <maketarget>do-extract</maketarget>, но никогда не трогайте
	  <maketarget>extract</maketarget>!</para>
      </note>

      <para>Теперь вы представляете, что происходит, когда пользователь
	набирает команду <command>make</command>, теперь давайте пройдемся
	через рекомендуемые для создания настоящего порта шаги.</para>
    </sect1>

    <sect1>
      <title>Получение исходного кода</title>

      <para>Получите оригинальные исходные тексты (обычно) в виде
	упакованного tar-архива
	(<filename><replaceable>foo</replaceable>.tar.gz</filename> или
	<filename><replaceable>foo</replaceable>.tar.Z</filename>)
	и скопируйте его в каталог <makevar>DISTDIR</makevar>.	Всегда
	используйте исходные тексты <emphasis>основной ветки
	разработки</emphasis> везде, где это возможно.</para>

      <para>Если вы не можете найти FTP/http сайт с хорошим подключением к
	сети, или находите только сайты, которые имеют раздражающе
	нестандартные форматы, то можете захотеть поместить копию на надежный
	сервер FTP или http, который вам доступен (например, ваша домашняя
	страница).  Проверьте, что вы установили переменную
	<makevar>MASTER_SITES</makevar> в значение, которое соответствует
	вашему решению.</para>

      <para>Если вы не можете найти доступного и надёжного места для
	помещения дистрибутивного файла, то мы сами сможем разместить его на
        сервере <hostid>ftp.FreeBSD.org</hostid>.  Дистрибутивный файл должен
        быть помещён в каталог <filename>~/public_distfiles/</filename>
        одного из пользователей машины <hostid>freefall</hostid>.  Попросите
        того, кто коммиттил ваш порт, сделать это.  Этот человек также задаст
        переменной <makevar>MASTER_SITES</makevar> значение
        <makevar>MASTER_SITE_LOCAL</makevar>, а в переменной
        <makevar>MASTER_SITE_SUBDIR</makevar> укажет своё имя пользователя
        с машины <hostid>freefall</hostid>.</para>

      <para>Если дистрибутивные файлы вашего порта постоянно меняются по
	непонятным причинам, остается поместить дистрибутив на вашу домашнюю
	веб-страницу и указать ее первой в списке
	<makevar>MASTER_SITES</makevar>.  Это позволит избежать получения
	ошибок <errorname>checksum mismatch</errorname> у пользователей, а
	также уменьшит нагрузку на людей, сопровождающих наш FTP-сервер.
	Также, если у порта имеется только один основной сервер, то
	рекомендуется поместить архивную копию на свой сайт и указать его в
	списке <makevar>MASTER_SITES</makevar> вторым.</para>

      <para>Если вашему порту требуются дополнительные `патчи', доступные
	в Интернет, скачайте также и их, поместив в каталог
	<makevar>DISTDIR</makevar>.  Не волнуйтесь, если они находятся не
	на том же сайте, откуда взят дистрибутивный архив, мы умеем
	обрабатывать такие ситуации (смотрите описание <link
	linkend="porting-patchfiles">PATCHFILES</link> ниже).</para>
    </sect1>

    <sect1>
      <title>Модификация порта</title>

      <para>Распакуйте копию дистрибутивного файла в отдельный каталог и
	внесите изменения, которые необходимы для того, чтобы порт
	компилировался нормально в текущей версии FreeBSD.
	<emphasis>Тщательно отслеживайте</emphasis> все, что вы делаете,
	этот процесс вам предстоит автоматизировать.  Все, включая удаление,
	добавление или модификацию в файлах должны будут выполняться
	автоматически с помощью скриптов или файлов патчей, когда вы
	завершите работу над портом.</para>

      <para>Если вашему порту во время компиляции, установки и настройки
	требуется довольно много взаимодействовать с пользователем, то
	посмотрите на один из классических скриптов
	<application>Configure</application> Лэрри Уолла (Larry Wall) и
	сделайте сами что-либо подобное.  Предназначение новой коллекции
	портов - это сделать каждое приложение в стиле
	<quote>plug-and-play</quote> настолько, насколько это вообще возможно
	для конечного пользователя при минимальном использовании дискового
	пространства.</para>

      <note>
	<para>Если явно не указано обратное, то патчи, скрипты и другие
	  файлы, которые вы создали и предоставили для Коллекции Портов
	  FreeBSD, неявно подпадают под стандартные условия лицензии
	  BSD.</para>
      </note>
    </sect1>

    <sect1>
      <title>Создание патчей</title>

      <para>Файлы, которые добавлялись или изменялись в процессе создания
	порта, могут быть выявлены вызовом программы diff с рекурсией, а
	результат работы этой программы может быть в дальнейшем передан
	программе patch.  Каждый набор патчей, который вы собираетесь
	применить, должен быть собран в файл с именем
	<filename>patch-<replaceable>*</replaceable></filename>, где
	<replaceable>*</replaceable> означает порядок, в которой будут
	применяться патчи &mdash; это делается в
	<emphasis>алфавитном порядке</emphasis>, то есть сначала
	<literal>aa</literal>, затем <literal>ab</literal> и так далее.  Если
        хотите, вы можете использовать имена файлов, указывающие на имена
        файлов, к которым применяются патчи, такие, как 
        <filename>patch-Imakefile</filename> или
        <filename>patch-src-config.h</filename>.  Эти файлы должны находиться в
        каталоге <makevar>PATCHDIR</makevar>,
	откуда они будут взяты автоматически.  Все патчи должны быть сделаны
	относительно каталога <makevar>WRKSRC</makevar> (как правило,
	это каталог, в который распаковывается исходный архив и где будет
	выполняться построение).  Для упрощения внесения изменений и
	обновлений вы должны избегать наличия более чем одного патча для
	одного и того же файла (например, патчей
	<filename>patch-aa</filename> и <filename>patch-ab</filename>, оба
	меняющих файл
	<filename><makevar>WRKSRC</makevar>/foobar.c</filename>).</para>
    </sect1>

    <sect1>
      <title>Конфигурирование</title>

      <para>Поместите все дополнительные команды, требуемые для настройки,
	в ваш скрипт <filename>configure</filename> и сохраните его в
	подкаталоге <filename>scripts</filename>. Как отмечено выше, вы
	можете сделать это целями в файле <filename>Makefile</filename>
	и/или скриптами с именами <filename>pre-configure</filename> или
	<filename>post-configure</filename>.</para>
    </sect1>

    <sect1>
      <title>Обработка пользовательского ввода</title>

      <para>Если для построения, конфигурации или установки вашего порта
	требуется некоторый ввод со стороны пользователя, то задайте
	переменную <makevar>IS_INTERACTIVE</makevar> в вашем файле Makefile.
	В случае <quote>ночного построения</quote> это позволит пропустить
	ваш порт, если пользователь в своем окружении задал переменную
	<envar>BATCH</envar> (и если пользователь установил переменную
	<envar>INTERACTIVE</envar>, то будут строиться
	<emphasis>только</emphasis> порты, которые требуют взаимодействия
	с пользователем.</para>

      <para>При наличии разумных ответов на задаваемые вопросы, подходящих по
	умолчанию, также рекомендуется проверять переменную
	<makevar>PACKAGE_BUILDING</makevar> и выключать интерактивный скрипт,
	если он есть.  Это позволит нам строить пакаджи для помещения на
	компакт-диски и FTP-серверы.</para>
    </sect1>
  </chapter>

  <chapter>
    <title>Настройка файла Makefile</title>

    <para>Настройка файла Makefile достаточно проста, и мы снова
      предполагаем, что перед тем, как начать, вы посмотрите на существующие
      примеры.	К тому же в этом руководстве имеется <link
      linkend="porting-samplem">примерный Makefile</link>, так что взгляните
      на него и, пожалуйста, следуйте порядку переменных и разделов в этом
      образце, чтобы облегчить чтение вашего порта другими людьми.</para>

    <para>Итак, расположим решаемые задачи в порядке их возникновения при
      создании вашего нового файла Makefile:</para>

    <sect1>
      <title>Оригинальные исходный код</title>

      <para>Находится ли он в каталоге <makevar>DISTDIR</makevar> в виде
	стандартного упакованного архиватором gzip tar-архива с именем типа
        <filename>foozolix-1.2.tar.gz</filename>?  Если это так,
	можно перейти к следующему шагу.  Если нет, то вы должны попытаться
	переопределить некоторые из переменных
        <makevar>DISTNAME</makevar>, <makevar>EXTRACT_CMD</makevar>,
	<makevar>EXTRACT_BEFORE_ARGS</makevar>,
	<makevar>EXTRACT_AFTER_ARGS</makevar>,
	<makevar>EXTRACT_SUFX</makevar> или <makevar>DISTFILES</makevar> в
	зависимости от того, насколько необычен формат дистрибутивного файла.
	(Самый распространённый случай - это
	<literal>EXTRACT_SUFX=.tar.Z</literal>, когда tar-файл упакован
	обычной утилитой <command>compress</command>, а не архиватором
	<command>gzip</command>.)</para>

      <para>В худшем случае вы можете просто определить свою собственную цель
	<maketarget>do-extract</maketarget> для переопределения действий по
	умолчанию, хотя к этому нужно будет прибегать в очень редких случаях,
	если вообще придётся.</para>
    </sect1>

    <sect1>
      <title><makevar>PORTNAME</makevar> и
        <makevar>PORTVERSION</makevar></title>

      <para>В переменной <makevar>PORTNAME</makevar> вы должны указать
	основную часть имени вашего порта, а в переменной
        <makevar>PORTVERSION</makevar> - номер версии.</para>
    </sect1>

    <sect1>
      <title><makevar>PORTREVISION</makevar> и
        <makevar>PORTEPOCH</makevar></title>

      <sect2>
        <title><makevar>PORTREVISION</makevar></title>

        <para>Переменная <makevar>PORTREVISION</makevar> представляет собой
          монотонно увеличивающееся число, которое обнуляется при каждом
          увеличении значения переменной <makevar>PORTVERSION</makevar> (то есть
          каждый раз, когда создателями выпускается новый официальный релиз),
          и добавляется к имени пакаджа, если оно не равно нулю.  Значение
          <makevar>PORTREVISION</makevar> увеличивается каждый раз, когда
          в порте FreeBSD делаются изменения, которые достаточно сильно
          затрагивают содержимое или структуру соответствующего пакаджа.</para>

        <para>Примеры случаев, когда значение PORTREVISION должно быть
          увеличено:</para>

        <itemizedlist>
          <listitem>
	    <para>Добавление патчей для исправления пробелов в безопасности,
	      ошибок, или добавления новой функциональности в порт
	      FreeBSD.</para>
          </listitem>

          <listitem>
	    <para>Изменения в файле построения порта для включения и выключения
	      параметров, определяемых при компиляции пакаджа.</para>
          </listitem>

          <listitem>
	    <para>Изменения в списке упаковки или в поведении пакаджа во время
	      его установки (например, изменение скрипта, генерирующего
	      начальные данные для пакаджа, такие, как ssh-ключи для
	      хоста).</para>
          </listitem>

          <listitem>
	    <para>Увеличение версии динамической библиотеки, от которой зависит
	      порт (в этом случае тот, кто попытается установить старый пакадж
	      после установки более новой версии библиотеки, не сможет этого
	      сделать, потому что при этом будет делаться поиск старой
              библиотеки libfoo.x, а не libfoo.(x+1)).</para>
          </listitem>

          <listitem>
	    <para>Большие функциональные изменения в дистрибутивном файле порта,
	      происходящие без объявлений, и приводящие к большим изменениям, то
	      есть изменения в дистрибутиве требуют корректировки файла
              <filename>distinfo</filename> без соответствующего изменения
              <makevar>PORTVERSION</makevar>, когда как команда
              <command>diff -ru</command> между новой и старой версиями
              показывает нетривиальные изменения в коде.</para>
          </listitem>
        </itemizedlist>

        <para>Примеры изменений, которые не требуют увеличения переменной
          <makevar>PORTREVISION</makevar>:</para>

        <itemizedlist>
          <listitem>
	    <para>Изменения стиля в скелете порта без функциональных изменений
	      в пакадже.</para>
          </listitem>

          <listitem>
	    <para>Изменения в переменной <makevar>MASTER_SITES</makevar> или
	      другие функциональные изменения порта, которые не затрагивают
	      получающегося пакаджа.</para>
          </listitem>

          <listitem>
	    <para>Тривиальные патчи к дистрибутивному файлу, такие, как
	      исправления опечаток, которые не так уж важны, что пользователи
	      пакаджа должны озаботиться обновлением.</para>
          </listitem>

          <listitem>
	    <para>Исправления, касающиеся этапа построения, которые делают
	      возможным построение пакаджа, если ранее это было невозможно
	      сделать (пока изменения не приводят к изменению работы на любых
	      других платформах, на которых порт ранее строился).  Так как
	      <makevar>PORTREVISION</makevar> отражает содержимое пакаджа, то
	      если ранее пакадж не строился, то нет нужды увеличивать
	      <makevar>PORTREVISION</makevar> для отметки изменения.</para>
          </listitem>
        </itemizedlist>

        <para>Правило, которому нужно приблизительно следовать, заключается в
          том, что нужно спрашивать себя, является ли вносимое в порт изменение
          таким, что кто-либо и где-либо от него выиграет (в виде
          усовершенствования, исправления или благодаря тому, что новый пакадж
          будет реально работать).  Если это так, то переменная
          <makevar>PORTREVISION</makevar> должна быть увеличена, чтобы
          автоматизированные инструменты (например,
          <command>pkg_version</command>) смогли обнаружить факт появления
          нового пакаджа.</para>
      </sect2>

      <sect2>
        <title><makevar>PORTEPOCH</makevar></title>

        <para>Время от времени разработчик программного обеспечения или
          создатель порта FreeBSD делают что-то не так и выпускают версию
          программы, номер которой меньше предыдущей версии.  Примером этого
          является порт, название которого меняется с foo-20000801 на foo-1.0
          (изначально это не считалось бы более новой версией, так как
          20000801 численно больше, чем 1).</para>
      
        <para>В ситуациях, подобных этой, должно быть увеличено значение
          <makevar>PORTEPOCH</makevar>.  Если значение
          <makevar>PORTEPOCH</makevar> не равно нулю, то оно добавляется к имени
          пакаджа, как описано в разделе выше.  Значение
          <makevar>PORTEPOCH</makevar> никогда не уменьшается и не сбрасывается
          в ноль, потому что это приведет к ошибке сравнения с пакаджем с
          меньшим номером эпохи (то есть то, что пакадж устарел. обнаружено не
          будет): номер новой версии (например, <literal>1.0,1</literal> в
          примере выше) останется меньше, чем номер предыдущей версии
          (20000801), однако суффикс <literal>,1</literal> интерпретируется
          различными автоматизированными утилитами особым образом, и окажется
          больше, чем предполагаемый суффикс ",0" более раннего пакаджа).</para>

        <para>Предполагается, что в большинстве портов переменная
          <makevar>PORTEPOCH</makevar> использоваться не будет, но при
          корректном использовании <makevar>PORTVERSION</makevar> может
          появиться необходимость её иметь, если в будущих релизах программное
          обеспечение должно изменить структуру номера версии.	Однако
          создателям портов нужно быть внимательными, когда разработчик
          выпускает релиз без официального номера версии - эдакие
          "промежуточные" релизы.  Имеется соблазн пометить релиз датой его
          выхода, что может вызвать проблемы, как и в примере выше, когда
          будет выпущен новый "официальный" релиз.</para>

        <para>Например, если промежуточный релиз помечен датой 20000917, а
          предыдущая версия программного обеспечения имела номер 1.2, то
          промежуточному релизу должно быть поставлено в соответствие значение
          <makevar>PORTVERSION</makevar>, равное 1.2.20000917 или что-то
          похожее, но не 20000917, так как последующий релиз, скажем, 1.3,
          должен иметь численно большее значение.</para>
      </sect2>

      <sect2>
        <title>Пример использования переменных <makevar>PORTREVISION</makevar> и
          <makevar>PORTEPOCH</makevar></title>

        <para>Выполнен коммит порта gtkmumble, версии 0.10, в коллекцию
          портов.</para>

        <programlisting>
PORTNAME=      gtkmumble
PORTVERSION=   0.10
        </programlisting>

        <para>Значение <makevar>PKGNAME</makevar> станет равным
          <literal>gtkmumble-0.10</literal>.</para>

        <para>Обнаружен пробел в безопасности, что потребовало создания
          локального патча для FreeBSD.  Соответственно было увеличено значение
          переменной <makevar>PORTREVISION</makevar>.</para>

        <programlisting>
PORTNAME=      gtkmumble
PORTVERSIOn=   0.10
PORTREVISION=  1
        </programlisting>

        <para><makevar>PKGNAME</makevar> принимает значение
          <literal>gtkmumble-0.10_1</literal></para>

        <para>Разработчиком выпущена новая версия с номером 0.2 (оказалось, что
          под номером <literal>0.10</literal> автор имел в виду
          <literal>0.1.0</literal>, а не <quote>то, что будет выпущено после
          версии 0.9</quote> - извините, теперь уже поздно).  Так как новый
          младший номер версии <literal>2</literal> по значению меньше, чем
          номер предыдущей версии <literal>10</literal>, то должно быть
          увеличено значение <makevar>PORTEPOCH</makevar> для того, чтобы
          заставить распознавать вновь создаваемый пакадж как "более новый".
          Так как это новый релиз программы, то <makevar>PORTREVISION</makevar>
          обнуляется (или удаляется из make-файла).</para>

        <programlisting>
PORTNAME=      gtkmumble
PORTVERSION=   0.2
PORTEPOCH=     1
        </programlisting>

        <para><makevar>PKGNAME</makevar> принимает значение
          <literal>gtkmumble-0.2,1</literal></para>

        <para>Следующий релиз имеет номер версии 0.3.  Так как значение
          переменной <makevar>PORTEPOCH</makevar> никогда не уменьшается, что
          переменные, определяющие версии, теперь выглядят так:</para>

        <programlisting>
PORTNAME=      gtkmumble
PORTVERSION=   0.3
PORTEPOCH=     1
        </programlisting>

        <para><makevar>PKGNAME</makevar> принимает значение
          <literal>gtkmumble-0.3,1</literal></para>

        <note>
          <para>Если значение <makevar>PORTEPOCH</makevar> этим
            обновлением было бы сброшено в <literal>0</literal>, то кто-нибудь,
            имеющий установленный пакадж gtkmumble-0.10_1, не смог бы распознать
            пакадж gtkmumble-0.3 как более новый, так как <literal>3</literal>
            было бы меньше, чем <literal>10</literal>.</para>
        </note>
      </sect2>
    </sect1>

    <sect1>
      <title>Переменные <makevar>PKGNAMEPREFIX</makevar>
        и <makevar>PKGNAMESUFFIX</makevar></title>

      <para>Две необязательные переменные, <makevar>PKGNAMEPREFIX</makevar> и
        <makevar>PKGNAMESUFFIX</makevar>, объединяются со значениями
        <makevar>PORTNAME</makevar> и
        <makevar>PORTVERSION</makevar> для формирования
        <makevar>PKGNAME</makevar> в форме
        <literal>${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}</literal>.
        Добейтесь того, чтобы это соответствовало нашим <link
        linkend="porting-pkgname">рекомендациям по правильному выбору названий
        для пакаджей</link>.  В частности, в переменной
        <makevar>PORTVERSION</makevar> не разрешается использование дефиса
        (<literal>-</literal>).  Кроме того, если в имени пакаджа
        присутствует часть <replaceable>language-</replaceable> или
        <replaceable>compiled.specifics</replaceable>, то используйте
        переменные <makevar>PKGNAMEPREFIX</makevar> и
        <makevar>PKGNAMESUFFIX</makevar>, соответственно.  Не делайте их
        частью значения переменной <makevar>PORTNAME</makevar>.</para>
    </sect1>

  <sect1>
    <title><makevar>DISTNAME</makevar></title>

    <para>В переменной <makevar>DISTNAME</makevar> указывается имя порта так,
      как назвали его создатели программного обеспечения.  Значение
      <makevar>DISTNAME</makevar> по умолчанию совпадает с
      <literal>${PORTNAME}-${PORTVERSION}</literal>, так что переопределите
      её значение в случае
      необходимости.  <makevar>DISTNAME</makevar> используется только в двух
      местах.  Во-первых, список дистрибутивных файлов
      (<makevar>DISTFILES</makevar>) по умолчанию состоит из
      <makevar>${DISTNAME}</makevar><makevar>${EXTRACT_SUFX}</makevar>.  И
      во-вторых, предполагается, что дистрибутивный файл будет распакован в
      подкаталог с именем <makevar>WRKSRC</makevar>, значение которого по
      умолчанию есть не что иное, как
      <filename>work/<makevar>${DISTNAME}</makevar></filename>.</para>

    <note>
      <para>Значения переменных <makevar>PKGNAMEPREFIX</makevar>
        и <makevar>PKGNAMESUFFIX</makevar> не влияют на значение
        <makevar>DISTNAME</makevar>.  Заметьте также, что значение
        <makevar>WRKSRC</makevar> равно
        <filename>work/<makevar>${PORTNAME}-${PORTVERSION}</makevar></filename>,
        и в случае, когда оригинальный архив называется по имени, отличном от
        <makevar>${PORTNAME}-${PORTVERSION}${EXTRACT_SUFX}</makevar>,
        скорее всего, вы должны оставить <makevar>DISTNAME</makevar>
        как есть&mdash; лучше переопределить <makevar>DISTFILES</makevar>,
        чем задавать значения как
        <makevar>DISTNAME</makevar>, так и <makevar>WRKSRC</makevar>
        (и, возможно, ещё и <makevar>EXTRACT_SUFX</makevar>).</para>
    </note>
  </sect1>

    <sect1>
      <title><makevar>CATEGORIES</makevar></title>

      <para>В процессе создания пакаджа он помещается в каталог
	<filename>/usr/ports/packages/All</filename>, а в одном или более
	подкаталогов из <filename>/usr/ports/packages</filename>
	создаются на него ссылки.  Имена этих подкаталогов определяются
	переменной <makevar>CATEGORIES</makevar>.  Такая схема нужна для
	облегчения жизни пользователя, когда он сталкивается с массой
	пакаджей на FTP-сервере или компакт-диске.  Пожалуйста, посмотрите на
	список существующих <link
	linkend="porting-categories">категорий</link> и выберите те из них,
	которые более всего подходят к вашему порту.</para>

      <para>Этот список также определяет, куда в дереве портов будет помещен
	порт.  Если вы укажете здесь более одной категории, то
	предполагается, что файлы порта будут помещены в подкаталог с именем
	первой категории.  Посмотрите раздел о <link
	linkend="porting-categories">категориях</link> для получения
	подробной информации о том, как правильно выбрать категории.</para>

      <para>Если ваш порт действительно относится к чему-то, что абсолютно
	не имеет отношения ни к одной из существующих категорий, вы можете
	даже создать новую категорию.  В этом случае, пожалуйста, пошлите
	письмо с вашим предложением на адрес &a.ports;.</para>
    </sect1>

    <sect1>
      <title><makevar>MASTER_SITES</makevar></title>

      <para>Содержит часть с каталогом ftp/http-URL, которая указывает на
	оригинальный архив на сервере <makevar>MASTER_SITES</makevar>.	Не
	забудьте лидирующий слэш (<filename>/</filename>)!</para>

      <para>Макрос команды <command>make</command> будет пытаться
	воспользоваться этой переменной для получения дистрибутивного файла
	с помощью программы <makevar>FETCH</makevar>, если он не будет найден
	в системе.</para>

      <para>Рекомендуется помещать в список много сайтов, предпочтительно с
	разных континентов.  Это поможет при наличии проблем с мировой сетью,
	и мы даже планируем добавить поддержку автоматического определения
	ближайшего сайта и сгрузки файлов оттуда!</para>

      <para>Если оригинальный архив находится на одном из таких популярных
        серверов, как X-contrib, GNU или Perl CPAN, то указывайте эти сайты в
        простой форме при помощи
        <makevar>MASTER_SITE_<replaceable>*</replaceable></makevar>
        (к примеру, <makevar>MASTER_SITE_XCONTRIB</makevar> или
        <makevar>MASTER_SITE_PERL_GNU</makevar>).  Просто укажите в переменной
        <makevar>MASTER_SITES</makevar> одно из этих значений, а в 
	переменной <makevar>MASTER_SITE_SUBDIR</makevar> задайте путь к архиву.
	Вот пример:</para>

      <programlisting>
MASTER_SITES=	      ${MASTER_SITE_XCONTRIB}
MASTER_SITE_SUBDIR=   applications
      </programlisting>

      <para>Эти переменные пределены в файле
        <filename>/usr/ports/Mk/bsd.sites.mk</filename>.  Всё время добавляются
        новые сайты, так что обращайтесь к последней версии этого файла перед
        тем, как послать нам свой порт.</para>

      <para>Пользователь может также задать значения переменных
	<makevar>MASTER_SITE_*</makevar> в файле
	<filename>/etc/make.conf</filename> для того, чтобы переопределить
	выбранные нами варианты, и использовать вместо них свои любимые
	зеркала этих популярных архивов.</para>
    </sect1>

    <sect1 id="porting-patchfiles">
      <title><makevar>PATCHFILES</makevar></title>

      <para>Если вашему порту требуются некоторых дополнительные патчи,
	которые доступны по FTP или http, задайте имена этих файлов в
	переменной <makevar>PATCHFILES</makevar>, а в переменной
	<makevar>PATCH_SITES</makevar> укажите URL того каталога, в котором
	они содержатся (формат такой же, как
	для <makevar>MASTER_SITES</makevar>).</para>

      <para>Если патч не относится к самому верху дерева исходных текстов
	(то есть <makevar>WRKSRC</makevar>), потому что он содержит некоторые
	дополнительные пути, установите соответственно значение переменной
	<makevar>PATCH_DIST_STRIP</makevar>.  В частности, если все имена
	путей в патче имеют дополнительный путь
	<literal>foozolix-1.0/</literal> перед именем файла, то задайте
	<literal>PATCH_DIST_STRIP=-p1</literal>.</para>

      <para>Не волнуйтесь, если патчи упакованы; они будут распакованы
	автоматически, если имена файлов оканчиваются на
	<filename>.gz</filename> или <filename>.Z</filename>.</para>

      <para>Если патч распространяется вместе с какими-то другими файлами,
	такими, как документация, в виде tar-архива gzip, вы не можете просто
	использовать <makevar>PATCHFILES</makevar>.  Если это ваш случай,
	добавьте имя и местоположение архива с патчем к
	<makevar>DISTFILES</makevar> и <makevar>MASTER_SITES</makevar>.
        Затем воспользуйтесь переменной <makevar>EXTRA_PATCHES</makevar> для
        указания этих файлов, и <filename>bsd.port.mk</filename> автоматически
        применит эти патчи.  В частности, <emphasis>не копируйте</emphasis>
        файлы с патчами в каталог <makevar>PATCHDIR</makevar>&mdash;этот
        каталог может быть недоступным для записи.</para>

      <note>
	<para>Отметьте, что архив будет распакован вне исходного кода, как
	  обычно, и к тому же его не нужно явно распаковывать, если
	  это обычный архив gzip или compress.	Если вы сделаете последнее,
	  приложите дополнительные усилия для того, чтобы не перезаписать
	  что-либо, уже существующее в этом каталоге.  Также не забудьте
	  добавить команду для удаления скопированного патча в цели
	  <maketarget>pre-clean</maketarget>.</para>
      </note>
    </sect1>

    <sect1>
      <title><makevar>MAINTAINER</makevar></title>

      <para>Укажите здесь ваш адрес электронной почты.	Пожалуйста.
	<!-- smiley --><emphasis>:-)</emphasis></para>

      <para>Подробное описание того, за что отвечает лицо, поддерживающее
	порт, даётся в главе <ulink
	url="../developers-handbook/policies.html#POLICIES-MAINTAINER">
        MAINTAINER в Makefiles</ulink>.</para>
    </sect1>

    <sect1>
      <title>Зависимости</title>

      <para>Многие порты зависят от других портов.  Имеется пять переменных,
	которые вы можете использовать для обеспечения того, что все
	требуемое находится на машине пользователя.  Имеется также несколько
	предопределенных переменных, отражающих зависимости для общих
	случаев, плюс еще несколько для управления поведением
	зависимостей.</para>

      <sect2>
	<title><makevar>LIB_DEPENDS</makevar></title>

	<para>Эта переменная указывает, от каких совместно используемых
	  библиотек зависит порт.  Это список пар
	  <replaceable>lib</replaceable>:<replaceable>dir</replaceable><optional><replaceable>:target</replaceable></optional>
	  где <replaceable>lib</replaceable> - это имя библиотеки,
	  <replaceable>dir</replaceable> - это каталог, в котором можно ее
	  найти в случае, если ее нет на машине, и
	  <replaceable>target</replaceable> - это цель, которую нужно вызвать
	  в этом каталоге.  Например, <programlisting> LIB_DEPENDS=
	  jpeg.9:${PORTSDIR}/graphics/jpeg:install</programlisting>
	  проверит наличие библиотеки jpeg со старшим номером версии 9 и
	  перейдет в подкаталог <filename>graphics/jpeg</filename> вашего
	  дерева портов для ее построения и установки, если библиотека
	  отсутствует.	Часть <replaceable>target</replaceable> может быть
	  опущена, если она равна <makevar>DEPENDS_TARGET</makevar>
	  (по умолчанию <literal>install</literal>).</para>

	<note>
	  <para>Часть <replaceable>lib</replaceable> - это аргумент, который
	    передается команде <command>ldconfig -r | grep -wF</command>.  В
	    этой переменной не должно быть регулярных выражений.</para>
	</note>

	<para>Зависимость проверяется дважды, один раз внутри цели
	  <maketarget>extract</maketarget>, а затем из цели
	  <maketarget>install</maketarget>.  Кроме того, имя зависимости
	  помещается в пакадж, так что <command>pkg_add</command> будет
	  автоматически его устанавливать, если его нет на пользовательской
	  системе.</para>
      </sect2>

      <sect2>
	<title><makevar>RUN_DEPENDS</makevar></title>

	<para>В этой переменной перечисляются выполнимые файлы или файлы, от
	  которых зависит работа порта.  Это список пар вида
	  <replaceable>path</replaceable>:<replaceable>dir</replaceable><optional><replaceable>:target</replaceable></optional>
	  где <replaceable>path</replaceable> - это имя программы или файла,
	  а <replaceable>dir</replaceable> - каталог, в котором можно найти
	  порт в случае, если его нет в системе, и
	  <replaceable>target</replaceable> - это цель, которую нужно вызвать
	  в этом каталоге.  Если <replaceable>path</replaceable> начинается
	  со слэша (<literal>/</literal>), он воспринимается как файл и его
	  существование проверяется командой <command>test -e</command>; в
	  противном случае предполагается, что это выполнимый файл и
	  для определения того, имеется ли программа в пути поиска
	  пользователя, используется команда
	  <command>which -s</command>.</para>

	<para>Например,</para>

	<programlisting>
RUN_DEPENDS=   ${PREFIX}/etc/innd:${PORTSDIR}/news/inn \
	       wish8.0:${PORTSDIR}/x11-toolkits/tk80
	</programlisting>

	<para>проверит, существует ли файл или каталог
	  <filename>/usr/local/etc/innd</filename> и построит и установит его
	  из подкаталога <filename>news/inn</filename> дерева портов, если он
	  не будет найден.  Он также проверит, имеется ли выполнимый файл с
	  именем <command>wish8.0</command> в вашем пути поиска, перейдет в
	  подкаталог <filename>x11-toolkits/tk80</filename> вашего дерева
	  портов для его построения и установки, если он не будет
	  найден.</para>

	<note>
	  <para>В приведенном примере <command>innd</command> является
	    выполнимым файлом; если выполнимый файл находится в необычном для
	    пользовательского маршрута поиска файлов месте, вы должны указать
	    полный путь к файлу.</para>
	</note>

	<para>Зависимость проверяется внутри цели
	  <maketarget>install</maketarget>. Кроме того, имя зависимости
	  помещается в пакадж, так что программа <command>pkg_add</command>
	  будет автоматически его устанавливать, если он не будет найден
	  в пользовательской системе.  Часть
	  <replaceable>target</replaceable> может быть опущена, если она
	  совпадает с <makevar>DEPENDS_TARGET</makevar>.</para>
      </sect2>

      <sect2>
	<title><makevar>BUILD_DEPENDS</makevar></title>

	<para>В этой переменной перечисляются выполнимые или обычные файлы,
	  которые требуются порту для его построения.  Как и
	  <makevar>RUN_DEPENDS</makevar>, это список пар
	  <replaceable>path</replaceable>:<replaceable>dir</replaceable><optional><replaceable>:target</replaceable></optional>
	  Например, <programlisting> BUILD_DEPENDS=
	  unzip:${PORTSDIR}/archivers/unzip</programlisting> будет проверять
	  наличие выполнимого фала с именем <command>unzip</command> и
	  перейдет в подкаталог <filename>archivers/unzip</filename> вашего
	  дерева портов для его построения и установки, если последний не
	  будет найден.</para>

	<note>
	  <para>Под <quote>построением</quote> здесь понимается всё, от
	    распаковки до компиляции.  Зависимость проверяется из цели
	    <maketarget>extract</maketarget>.  Часть
	    <replaceable>target</replaceable> может быть опущена, если она
	    совпадает с <makevar>DEPENDS_TARGET</makevar>.</para>
	</note>
      </sect2>

      <sect2>
	<title><makevar>FETCH_DEPENDS</makevar></title>

	<para>В этой переменной перечисляются выполняемые файлы или просто
	  файлы, которые требуются порту для сгрузки.  Как и предыдущие две
	  переменные, это список пар
	  <replaceable>path</replaceable>:<replaceable>dir</replaceable><optional><replaceable>:target</replaceable></optional>
	  Например, <programlisting> FETCH_DEPENDS=
	  ncftp2:${PORTSDIR}/net/ncftp2</programlisting> будет проверять
	  наличие выполняемого файла с именем <command>ncftp2</command> и
	  перейдет в каталог <filename>net/ncftp2</filename> вашего дерева
	  портов для его построения и установки, если тот не будет
	  найден.</para>

	<para>Зависимость проверяется при выполнении цели
	  <maketarget>fetch</maketarget>.  Часть
	  <replaceable>target</replaceable> может быть опущена, если она
	  совпадает с <makevar>DEPENDS_TARGET</makevar>.</para>
      </sect2>

      <sect2>
	<title><makevar>DEPENDS</makevar></title>

	<para>Если имеется зависимость, которая не подпадает ни под одну из
	  вышеперечисленных четырех категорий, или ваш порт требует наличия
	  исходных текстов другого порта в распакованном виде кроме того,
	  что этот порт должен быть установлен, то воспользуйтесь этой
	  переменной.  Это список пар
	  <replaceable>dir</replaceable><optional><replaceable>:target</replaceable></optional>,
	  потому что, в отличие от предыдущих случаев, ничего не
	  проверяется.	Часть <replaceable>target</replaceable> может
	  быть опущена, если она совпадает с
	  <makevar>DEPENDS_TARGET</makevar>.</para>
      </sect2>

      <sect2>
	<title>Переменные зависимостей общего вида</title>

	<para>Определите переменную <literal>USE_XLIB=yes</literal>, если ваш
	  порт для установки требует X Window System (что подразумевается при
	  использовании переменной <makevar>USE_IMAKE</makevar>).  Определите
	  переменную <literal>USE_GMAKE=yes</literal>, если ваш порт требует
	  вместо стандартной для BSD утилиты <command>make</command> ее
	  GNU-аналог.  Задайте <literal>USE_AUTOCONF=yes</literal>, если
	  порту для работы требуется GNU autoconf.  Определите переменную
	  <literal>USE_QT=yes</literal>, если ваш порт использует самую
	  последнюю версию пакета qt.  Укажите
	  <literal>USE_PERL5=yes</literal> в случае, если вашему порту
	  требуется версия 5 языка perl.  (Последнее особенно важно, так как
	  некоторые версии FreeBSD имеют perl5 в составе системы, когда как
	  другие - нет.)</para>
      </sect2>

      <sect2>
	<title>Замечания касательно зависимостей</title>

	<para>Как уже отмечено выше, целью, которая вызывается по умолчанию
	  в случае, когда это требует зависимость, является
	  <maketarget>DEPENDS_TARGET</maketarget>.  Она по умолчанию есть
	  <literal>install</literal>.  Это пользовательская переменная; она
	  нигде не определена в файле <filename>Makefile</filename> порта.
	  Если вашему порту требуется особый метод обработки зависимости,
	  воспользуйтесь частью <literal>:target</literal> переменной
	  <makevar>*_DEPENDS</makevar> вместо того, чтобы переопределять
	  <makevar>DEPENDS_TARGET</makevar>.</para>

	<para>Когда вы набираете команду <command>make clean</command>,
	  эта операция также выполняется и над зависимостями этого порта.
	  Если вы не хотите, чтобы это случилось, определите переменную
	  <makevar>NOCLEANDEPENDS</makevar> в вашем окружении.</para>

	<para>Чтобы безусловно зависеть от другого порта, укажите переменную
          <makevar>${NONEXISTENT}</makevar> в качестве первого поля
	  переменной <makevar>BUILD_DEPENDS</makevar> или
	  <makevar>RUN_DEPENDS</makevar>.  Пользуйтесь этим, только когда вам
	  нужно иметь исходный код другого порта.  Вы можете сэкономить время
	  на компиляции, указав также и цель.  Например,
          <programlisting>
BUILD_DEPENDS=   ${NONEXISTENT}:${PORTSDIR}/graphics/jpeg:extract
          </programlisting>
          всегда будет переходить в каталог с портом JPEG и распаковывать
	  его.</para>

	<para>Не нужно использовать <makevar>DEPENDS</makevar>, если есть
	  другой способ получить требуемый результат.  Это может привести к
	  тому, что какой-то другой порт всегда будет строиться (и по
	  умолчанию устанавливаться). и такая зависимость отразится и на
	  пакадже.  Если это именно то, что вам нужно, то вам, наверное,
          следует описывать это через <literal>BUILD_DEPENDS</literal> и
	  <literal>RUN_DEPENDS</literal>&mdash;по крайней мере смысл
	  будет более понятен.</para>
      </sect2>
    </sect1>

    <sect1>
      <title>Опциональные зависимости</title>

      <para>Некоторые большие приложения могут быть построены в различных
        конфигурациях, с дополнительной функциональностью, зависящей от наличия
        в системе определенных библиотек или приложений.  Так как не всем
        пользователям требуются эти библиотеки или приложения, то в системе
        портов предусмотрен механизм, позволяющий автору порта принимать решение
        о конфигурации, которая будет строиться.  Полная поддержка этого
        механизма облегчает использование порта и дает два или более порта ценой
        создания одного.</para>

      <para>Самым простым из этих механизмом является использование
        <makevar>WITHOUT_X11</makevar>.  Если порт может быть построен как с
        поддержкой X, так и без оной, то обычно он должен строиться с поддержкой
        X.  Если определена переменная <makevar>WITHOUT_X11</makevar>, то должна
        строиться версия, не поддерживающая X.</para>

      <para>Различные части пакета GNOME имеют такие зависимости, хотя их
        гораздо труднее использовать.  В <filename>Makefile</filename> можно
        использовать переменные <makevar>WANT_*</makevar> и
        <makevar>HAVE_*</makevar>.  Если приложение может быть построено как с
        зависимостями, так и без зависимостей, перечисленных ниже, то в
        <filename>Makefile</filename> должна быть задана переменная
        <makevar>WANT_PKG</makevar> и версия, которая использует пакет
        <makevar>PKG</makevar>, будет строиться, если определена переменная
        <makevar>HAVE_PKG</makevar>.</para>

      <para>На данный момент так работают переменные <makevar>WANT_*</makevar>,
        <makevar>WANT_GLIB</makevar>, <makevar>WANT_GTK</makevar>,
        <makevar>WANT_ESOUND</makevar>, <makevar>WANT_IMLIB</makevar>
        и <makevar>WANT_GNOME</makevar>.</para>
    </sect1>

    <sect1>
      <title>Механизм построения</title>

      <para>Если ваш пакадж использует GNU-версию утилиты
	<command>make</command>, задайте <literal>USE_GMAKE=yes</literal>.
	Если ваш пакадж использует <command>configure</command>, задайте
	<literal>HAS_CONFIGURE=yes</literal>.  Если ваш пакадж использует
	GNU-версию <command>configure</command>, задайте
	<literal>GNU_CONFIGURE=yes</literal> (это также подразумевает
	<literal>HAS_CONFIGURE</literal>).  Если вы хотите передать
	дополнительные параметры в <command>configure</command> (список
	параметров представляет собой
	<literal>--prefix=&dollar;{PREFIX}</literal> для GNU
	<command>configure</command> и пустую строку для не-GNU
	<command>configure</command>), укажите эти дополнительные параметры в
	<makevar>CONFIGURE_ARGS</makevar>.  Если ваш пакадж использует
	GNU-версию <command>autoconf</command>, задайте
	<literal>USE_AUTOCONF=yes</literal>.  Это подразумевает
	<makevar>GNU_CONFIGURE</makevar>, и приведет к вызову
	<command>autoconf</command> до запуска
	<command>configure</command>.</para>

      <para>Если ваш пакадж является приложением для X, которое создает
	файлы <filename>Makefile</filename> из соответствующих файлов
	<filename>Imakefile</filename> при помощи утилиты
	<command>imake</command>, то задайте <literal>USE_IMAKE=yes</literal>.
	Это приведет к автоматическому запуску команды
	<command>xmkmf -a</command> на этапе конфигурирования.	Если
	использование флага <option>-a</option> является для вашего порта
	проблематичным, задайте <literal>XMKMF=xmkmf</literal>.  Если порт
	использует команду <command>imake</command>, но не воспринимает цель
	<maketarget>install.man</maketarget>, то должна быть задана
	переменная <literal>NO_INSTALL_MANPAGES=yes</literal>.	Кроме того,
	автор программы должен быть пристрелен. <!--
	smiley --><emphasis>:-&gt;</emphasis></para>

      <para>Если в файле <filename>Makefile</filename> из дистрибутива вашего
	порта в качестве главной цели для построения указано нечто, отличное
	от <maketarget>all</maketarget>, то задайте соответствующим образом
	переменную <makevar>ALL_TARGET</makevar>.  То же самое касается
	целей <maketarget>install</maketarget> и
	<makevar>INSTALL_TARGET</makevar>.</para>
    </sect1>
  </chapter>


<chapter>
  <title>Особые соглашения</title>

  <para>Имеется ещё несколько вещей, которые вы должны иметь в виду при
    создании порта.  Этот раздел описывает наиболее часто встречающиеся из
    них.</para>

  <sect1 id="porting-shlibs">
    <title>Динамические библиотеки</title>

    <para>Если ваш порт устанавливает одну или несколько динамических
      библиотек, определите переменную <makevar>INSTALLS_SHLIB</makevar>,
      которая приведёт к запуску из <filename>bsd.port.mk</filename> команды
      <literal>&dollar;{LDCONFIG} -m</literal> относительно каталога, в который
      устанавливается новая библиотека (как правило, это
      <filename><makevar>PREFIX</makevar>/lib</filename>), во время выполнения
      цели <maketarget>post-install</maketarget> для её регистрации в кэше
      динамических библиотек.  Эта переменная, если она определена, также
      приведёт к добавлению соответствующей пары команд
      <literal>@exec /sbin/ldconfig -m</literal> и
      <literal>@unexec /sbin/ldconfig -R</literal> в ваш файл
      <filename>pkg-plist</filename>, так что пользователь, устанавливающий
      пакадж, сможет сразу же использовать динамическую библиотеку, а удаление
      пакаджа не приведёт к тому, что система будет предполагать, что
      библиотека всё ещё имеется в наличии.</para>

    <para>Если нужно, вы можете переопределить каталог, в который по умолчанию
      устанавливается библиотека, задав переменную
      <makevar>LDCONFIG_DIRS</makevar>, в которой должны быть перечислены
      каталоги, в которые устанавливаются динамические библиотеки.  Например,
      если ваш порт устанавливает динамические библиотеки в каталоги
      <filename><makevar>PREFIX</makevar>/lib/foo</filename> и
      <filename><makevar>PREFIX</makevar>/lib/bar</filename>, то вы можете в
      файле <filename>Makefile</filename> указать следующее:</para>

    <programlisting>
INSTALLS_SHLIB= yes
LDCONFIG_DIRS=  %%PREFIX%%/lib/foo %%PREFIX%%/lib/bar
    </programlisting>

    <para>Заметьте, что значение переменной <makevar>LDCONFIG_DIRS</makevar>
      передаётся через &man.sed.1;, как и всё остальное в
      <filename>pkg-plist</filename>, так что подстановка значения
      <makevar>PLIST_SUB</makevar> также происходит здесь.  Рекомендуется
      использовать <literal>%%PREFIX%%</literal> для <makevar>PREFIX</makevar>,
      <literal>%%LOCALBASE%%</literal> для <makevar>LOCALBASE</makevar> и
      <literal>%%X11BASE%%</literal> для <makevar>X11BASE</makevar>.</para>
  </sect1>
</chapter>


<!--

  <chapter>
    <title>Поддержка ELF</title>

    <para>Так как вскоре после выхода 3.0-RELEASE во FreeBSD сменился формат
      исполнимых файлов на формат ELF, то мы должны во множестве
      портов, которые строят совместно используемые библиотеки, обеспечить
      поддержку этого формата.	Эту работу осложняет тот факт, что 3.0 может
      работать как в формате ELF, так и a.out, и к тому же мы хотим
      неофициально поддерживать ветку 2.2, насколько это возможно долго.
      Ниже даются указания по преобразованию портов, поддерживающих только
      a.aout, для компиляции как в формате a.aout, так и ELF.</para>

    <para>Некоторая часть этих указаний подходит только на время
      преобразования, но пока они здесь для справки в случае, если вы будете
      работать со старыми портами, которым нужно обновление.</para>

    <sect1>
      <title>Избавление от библиотек в формате a.out</title>

      <para>Все библиотеки в формате a.out из каталога
	<filename>/usr/local/lib</filename> и других похожих каталогов должны
	быть убраны в подкаталог <filename>aout</filename>.  (Если вы их не
	перенесете, то порты в формате ELF будут перезаписывать библиотеки
	в формате a.out.)  Цель <maketarget>move-aout-libs</maketarget> в
	<filename>src/Makefile</filename> из 3.0-CURRENT (которая вызывается
	из <maketarget>aout-to-elf</maketarget>) сделает это за вас.  Она
	перемещает только библиотеки в формате a.out, так что это можно
	без опаски сделать на системе с библиотеками в форматах ELF и a.out,
	находящимися в стандартных каталогах.</para>
    </sect1>

    <sect1>
      <title>Формат</title>

      <para>Пакаджи в дереве портов будут строиться в том формате, в котором
	работает машина.  Это означает формат a.out для 2.2 и a.out или ELF
	для 3.0 в зависимости от результата работы команды
	<command>`objformat`</command>.  Кроме того, как только пользователь
	переместит библиотеки формата a.out в соответствующий подкаталог,
	построение библиотек в формате a.out поддерживаться не будет.
	(Другими словами, это может продолжать работать, если вы знаете, как
	это делается, но помогать вам в этом никто не будет.)</para>

      <note>
	<para>Если порт работает только в формате a.out, задайте в переменной
	  <makevar>BROKEN_ELF</makevar> в качестве значения строчку,
	  описывающую причину этого.  Такие порты во время построения на
	  ELF-системе будут пропущены.</para>
      </note>
    </sect1>

    <sect1>
      <title><makevar>PORTOBJFORMAT</makevar></title>

      <para>В файле <filename>bsd.port.mk</filename> переменная
	<makevar>PORTOBJFORMAT</makevar> будет установлена в значение
	<literal>aout</literal> или <literal>elf</literal> и будет передана
	в переменные окружения <envar>CONFIGURE_ENV</envar>,
	<envar>SCRIPTS_ENV</envar> и <envar>MAKE_ENV</envar>.  (И всегда
	будет равно <literal>aout</literal> для 2.2-STABLE).  Она также
	будет передана в <maketarget>PLIST_SUB</maketarget> как
	<literal>PORTOBJFORMAT=${PORTOBJFORMAT}</literal>.  (Смотри
	замечания по поводу строк <literal>ldconfig</literal> ниже.)</para>

      <para>Значение переменной устанавливается с помощью такой строки из
	<filename>bsd.port.mk</filename>:</para>

      <programlisting>
PORTOBJFORMAT!= test -x /usr/bin/objformat && /usr/bin/objformat || echo aout
      </programlisting>

      <para>Процессы построения портов должны использовать эту переменную для
	того, чтобы решить, что делать.  Однако, если скрипт
	<filename>configure</filename> порта автоматически распознает
	ELF-систему, то к переменной <makevar>PORTOBJFORMAT</makevar>
	обращаться необязательно.</para>
    </sect1>

    <sect1>
      <title>Построение динамических библиотек</title>

      <para>Далее описываются отличия при работе с совместно используемыми
	библиотеками в форматах a.out и ELF.</para>

      <itemizedlist>
	<listitem>
	  <para>Версии совместно используемой библиотеки</para>

	  <para>Совместно используемая библиотека в формате ELF должна
	    называться
	    <filename>libfoo.so.<replaceable>M</replaceable></filename>,
	    где <replaceable>M</replaceable> - это одно число, задающее номер
	    версии, а библиотека в формате a.out должна называться
	    <filename>libfoo.so.<replaceable>M</replaceable>.<replaceable>N</replaceable></filename>,
	    где <replaceable>M</replaceable> - это старший номер версии, а
	    <replaceable>N</replaceable> - младший номер версии.
	    Не смешивайте эти вещи; <emphasis>никогда</emphasis> не
	    устанавливайте совместно используемую библиотеку в формате
	    ELF под именем <filename>libfoo.so.<replaceable>N</replaceable>.<replaceable>M</replaceable></filename>
	    или a.out-библиотеку (или символическую ссылку на нее) с именем
	    <filename>libfoo.so.<replaceable>N</replaceable></filename>.</para>
	</listitem>

	<listitem>
	  <para>Командные строки для компоновщика</para>

	  <para>Если предположить, что используется команда
	    <command>cc -shared</command>, а не непосредственно компоновщик
	    <command>ld</command>, то единственная разница заключается в том,
	    что в случае формата ELF вам нужно добавить
	    <option>-Wl,-<replaceable>soname,libfoo.so.M</replaceable></option>
	    в командной строке.</para>
	</listitem>
      </itemizedlist>

      <para>Вам нужно создать символическую ссылку
	<filename>libfoo.so</filename>, указывающую на
	<filename>libfoo.so.<replaceable>N</replaceable></filename>, для
	того, чтобы компоновщики ELF были удовлетворены.  Так как это должно
	быть также указано в файле <filename>pkg-plist</filename>, и это не
	мешает работе в случае a.out (некоторые порты даже требуют наличия
	такой ссылки для динамической загрузки), то вы должны просто сделать
	эту ссылку вне зависимости от значения переменной
	<makevar>PORTOBJFORMAT</makevar>.</para>
    </sect1>

    <sect1>
      <title><makevar>LIB_DEPENDS</makevar></title>

      <para>Во всех портах файлы Makefile были исправлены так, чтобы убрать
	младшие числа из <makevar>LIB_DEPENDS</makevar>, а избавиться от
	поддержки regexp.  (Например,
	<literal>foo\\.1\\.\\(33|40\\)</literal> стала
	<literal>foo.2</literal>.)  Они будут искаться с помощью команды
	<command>grep -wF</command>.</para>
    </sect1>

    <sect1>
      <title><filename>pkg-plist</filename></title>

      <para>Файл <filename>pkg-plist</filename> должен содержать краткие (ELF)
	имена совместно используемых библиотек, если младшее число формата
	a.out равно нулю, и длинные (a.out) имена в противном случае.  В
	<filename>bsd.port.mk</filename> в конец краткой строки будет
	автоматически добавлен <literal>.0</literal>, если
	<makevar>PORTOBJFORMAT</makevar> равен <literal>aout</literal>,
	и будет удалено младшее число из длинного имени, если
	<makevar>PORTOBJFORMAT</makevar> установлена в
	<literal>elf</literal>.</para>

      <para>В случаях, когда вам действительно нужно установить версию
	библиотеки с двумя номерами на ELF-системе или с одним номером на
	системе a.out (например, порты, которые устанавливают библиотеки
	обеспечения совместимости с другими операционными системами), то
	задайте переменную <makevar>NO_FILTER_SHLIBS</makevar>.  Это выключит
	редактирование файла <filename>pkg-plist</filename> так, как это указано
	в предыдущем параграфе.</para>
    </sect1>

    <sect1>
      <title><literal>ldconfig</literal></title>

      <para>Строка <literal>ldconfig</literal> в файлах Makefile
	должна иметь вид:</para>

      <programlisting>
${SETENV} OBJFORMAT=${PORTOBJFORMAT} ${LDCONFIG} -m ....
      </programlisting>

      <para>В файле <filename>pkg-plist</filename> она должна быть такой:</para>

      <programlisting>
@exec /usr/bin/env OBJFORMAT=%%PORTOBJFORMAT%% /sbin/ldconfig -m ...
@unexec /usr/bin/env OBJFORMAT=%%PORTOBJFORMAT%% /sbin/ldconfig -R
      </programlisting>

      <para>Это нужно для того, чтобы утилита <command>ldconfig</command>
	была вызвана правильно в зависимости от формата пакаджа, а не
	формата, используемого в системе по умолчанию.</para>
    </sect1>
  </chapter>

-->

  <chapter id="porting-masterdir">
    <title><makevar>MASTERDIR</makevar></title>

    <para>Если вашему порту требуется построение довольно различающихся
      версий пакаджей через переменную (задающую, например, разрешение,
      или размер бумаги), которая принимает различные значения, создайте для
      каждого пакаджа отдельный подкаталог, чтобы пользователям было легче
      определить, каким пакаджем воспользоваться, но попробуйте использовать
      совместно между портами как можно больше файлов.	В типичном случае вам
      потребуются только очень короткие файлы <filename>Makefile</filename>
      во всех каталогах, кроме одного, если вы будете использовать переменные
      с умом.  В отдельных файлах <filename>Makefiles</filename> вы можете
      использовать переменную <makevar>MASTERDIR</makevar> для указания
      каталога, в котором находятся все остальные файлы.  Также используйте
      переменную как часть <link
      linkend="porting-pkgname"><makevar>PKGNAMESUFFIX</makevar></link>, чтобы
      пакаджи имели разные имена.</para>

    <para>Продемонстрируем это на примере.  Вот часть файла
      <filename>japanese/xdvi300/Makefile</filename>:</para>

    <programlisting>
PORTNAME=       xdvi
PORTVERSION=    17
PKGNAMEPREFIX=  ja-
PKGNAMESUFFIX=  ${RESOLUTION}
 :
# default
RESOLUTION?=   300
.if ${RESOLUTION} != 118 && ${RESOLUTION} != 240 && \
       ${RESOLUTION} != 300 && ${RESOLUTION} != 400
       @${ECHO} "Error: invalid value for RESOLUTION: \"${RESOLUTION}\""
       @${ECHO} "Possible values are: 118, 240, 300 (default) and 400."
       @${FALSE}
.endif
    </programlisting>

    <para>Каталог <filename>japanese/xdvi300</filename> содержит также все
      обычные патчи, файлы для пакаджа и так далее.  Если вы введете здесь
      команду <command>make</command>, она возьмет в качестве разрешения
      значение по умолчанию (300) и построит порт обычным образом.</para>

    <para>Для другого разрешения приведем <emphasis>полный</emphasis>
      <filename>xdvi118/Makefile</filename>:</para>

    <programlisting>RESOLUTION=	118
MASTERDIR=	${.CURDIR}/../xdvi300

.include "${MASTERDIR}/Makefile"</programlisting>

    <para>(<filename>xdvi240/Makefile</filename> и
      <filename>xdvi400/Makefile</filename> похожи).  Задание
      <makevar>MASTERDIR</makevar> говорит <filename>bsd.port.mk</filename>,
      что обычный набор подкаталогов типа <makevar>FILESDIR</makevar> и
      <makevar>SCRIPTDIR</makevar> находится в каталоге
      <filename>xdvi300</filename>.  Строчка
      <literal>RESOLUTION=118</literal> переопределят строку
      <literal>RESOLUTION=300</literal> в файле
      <filename>xdvi300/Makefile</filename> и порт будет построен с
      разрешением 118.</para>
  </chapter>

  <chapter>
    <title>Версии динамических библиотек</title>

    <para>Первым делом прочтите, пожалуйста, наши <ulink
      url="../developers-handbook/policies-shlib.html">правила нумерации версий
      динамических библиотек</ulink> для понимания того, что делать с версиями
      совместно используемых библиотек вообще.  Не полагайтесь слепо на то,
      что авторы
      программного обеспечения знают, что творят; многие это не понимают.
      Очень важно с точностью следовать всем этим правилам, так как мы
      получаем достаточно уникальную ситуацию, когда пытаемся иметь несколько
      наборов потенциально несовместимых программных пакетов.  Невнимательное
      включение портов вызывало большие проблемы относительно совместно
      используемых библиотек в прошлом (вы когда либо задумывались, почему
      порт <filename>jpeg-6b</filename> имеет библиотеку версии 9?).	Если
      не уверены, пошлите сообщение по адресу &a.ports;.  В большинстве
      случаев ваша работа заканчивается определением правильного номера
      динамической библиотеки и созданием соответствующих патчей для
      реализации этого.</para>

<!--
    <para>Однако если в дереве портов имеется порт, который представляет
      собой другую версию той же самой программы, то ситуация гораздо более
      сложна.  Вкратце, реализация во FreeBSD не позволяет пользователю
      указать компоновщику, с какой версией совместно используемой
      библиотеки нужно выполнять компоновку (компоновщик всегда будет
      выбирать версию с максимальным номером).	Это означает, что если в
      системе присутствуют библиотеки <filename>libfoo.so.3.2</filename> и
      <filename>libfoo.so.4.0</filename>, то нет способа указать
      компоновщику компоновать отдельно взятое приложение с
      <filename>libfoo.so.3.2</filename>.  Это темный вопрос для компоновки
      во время компиляции.  В этом случае единственным решением является
      переименование <emphasis>имени</emphasis> библиотеки.  Например,
      переименуйте <filename>libfoo.so.4.0</filename> в
      <filename>libfoo4.so.1.0</filename>, чтобы обе версии, и 3.2, и 4.0,
      могли быть скомпонованы с разными портами.</para>
-->
  </chapter>

  <chapter id="porting-manpages">
    <title>Страницы Справочника</title>

    <para>Переменные <makevar>MAN[1-9LN]</makevar> автоматически добавят любые
      страницы Справочника к файлу <filename>pkg-plist</filename> (это
      означает, что вам <emphasis>не нужно</emphasis> указывать страницы
      Справочника в файле <filename>pkg-plist</filename>&mdash;обратитесь к
      главе о <link linkend="porting-plist">генерации файла PLIST</link> для
      получения более подробной информации).  Это также позволяет на этапе
      установки автоматически упаковывать и распаковывать страницы
      Справочника в зависимости от значения переменной
      <makevar>NOMANCOMPRESS</makevar> в файле
      <filename>/etc/make.conf</filename>.</para>

    <para>Если ваш порт пытается задать несколько имен для страниц
      Справочника при помощи символических или жестких ссылок, то вы должны
      использовать переменную <makevar>MLINKS</makevar>, чтобы указать на
      это.  Ссылка, установленная вашим портом, будет уничтожена и создана
      заново сценарием <filename>bsd.port.mk</filename> для проверки того,
      что она указывает на правильный файл.  Любые страницы Справочника,
      перечисленные в переменной MLINKS, не должны фигурировать в файле
      <filename>pkg-plist</filename>.</para>

    <para>Для указания того, что страницы Справочника нужно сжимать во
      время установки, используйте переменную
      <makevar>MANCOMPRESSED</makevar>.  Эта переменная может принимать три
      значения - <literal>yes</literal>, <literal>no</literal> и
      <literal>maybe</literal>.  <literal>yes</literal> означает, что
      страницы Справочника устанавливаются уже сжатыми, <literal>no</literal>
      означает, что они не сжимаются и <literal>maybe</literal> означает, что
      программное обеспечение принимает во внимание значение переменной
      <makevar>NOMANCOMPRESS</makevar>, так что сценарию
      <filename>bsd.port.mk</filename> ничего дополнительно делать не
      нужно.</para>

    <para>Значение переменной <makevar>MANCOMPRESSED</makevar> автоматически
      устанавливается в <literal>yes</literal>, если переменная
      <makevar>USE_IMAKE</makevar> задана, а
      <makevar>NO_INSTALL_MANPAGES</makevar> нет, и в значение
      <literal>no</literal> в противном случае.  Вам не нужно задавать ее
      явно, если значение по умолчанию подходит вашему порту.</para>

    <para>Если ваш порт определяет корнем для файлов Справочника каталог,
      отличный от <makevar>PREFIX</makevar>, вы можете использовать
      переменную <makevar>MANPREFIX</makevar>, чтобы задать его явно.  Кроме
      того, если страницы только некоторых разделов помещаются в
      нестандартное место, например, в случае портов модулей языка Perl, вы
      можете установить пути страниц Справочника индивидуально, при помощи
      <makevar>MAN<replaceable>sect</replaceable>PREFIX</makevar> (где
      <replaceable>sect</replaceable> принимает значения
      <literal>1-9</literal>, <literal>L</literal> или
      <literal>N</literal>).</para>

    <para>Если страницы Справочника помещаются в подкаталоги, соответствующие
      некоторому языку, то задайте название языка языка в переменной
      <makevar>MANLANG</makevar>.  Значение этой переменной по умолчанию
      равно <literal>""</literal> (то есть только английский язык).</para>

    <para>Вот пример, в котором приводятся все случаи.</para>

    <programlisting>
MAN1=	       foo.1
MAN3=	       bar.3
MAN4=	       baz.4
MLINKS=        foo.1 alt-name.8
MANLANG=       "" ja
MAN3PREFIX=    ${PREFIX}/share/foobar
MANCOMPRESSED= yes
    </programlisting>

    <para>Здесь указано, что этот порт устанавливает 6 файлов:</para>

    <programlisting>
${PREFIX}/man/man1/foo.1.gz
${PREFIX}/man/ja/man1/foo.1.gz
${PREFIX}/share/foobar/man/man3/bar.3.gz
${PREFIX}/share/foobar/man/ja/man3/bar.3.gz
${PREFIX}/man/man4/baz.4.gz
${PREFIX}/man/ja/man4/baz.4.gz
    </programlisting>

    <para>Кроме того, файл
      <filename>${PREFIX}/man/man8/alt-name.8.gz</filename> может быть, а
      может и не быть установлен вашим портом.	В любом случае будет создана
      символическая ссылка для объединения страниц Справочника foo(1) и
      alt-name(8).</para>
  </chapter>

  <chapter id="porting-motif">
    <title>Порты, которым требуется Motif</title>

    <para>Существует много приложений, которым для компиляции требуется
      библиотека Motif (которую можно приобрести у нескольких поставщиков,
      хотя есть и бесплатный клон в
      <filename>x11-toolkits/lesstif</filename>, о котором говорится, что с
      ним работает множество приложений).  Так как это распространенный пакет
      и его лицензионное соглашение обычно позволяет распространение
      статически скомпонованных бинарных файлов, мы обратили особое внимание
      на работу с портами, которым требуется Motif, так чтобы мы могли
      легко создавать бинарные файлы, скомпонованные как динамически (для
      тех, кто строит приложение из порта), так и статически (для тех, кто
      будет распространять приложения в виде пакаджей).</para>

    <sect1>
      <title><makevar>REQUIRES_MOTIF</makevar></title>

      <para>Если вашему порту требуется Motif, задайте эту переменную в
	файле Makefile.  Это не позволит людям, у которых нет собственной
	копии Motif, даже попытаться построить порт.</para>
    </sect1>

    <sect1>
      <title><makevar>MOTIFLIB</makevar></title>

      <para>Эта переменная будет установлена сценарием
	<filename>bsd.port.mk</filename> в соответствующее значение,
	соответствующее библиотеке Motif.  Пожалуйста, измените исходные
	тексты для использования этой переменной там, где упоминается
	библиотека Motif, в <filename>Makefile</filename> или
	<filename>Imakefile</filename>.</para>

      <para>Могут быть два случая:</para>

      <itemizedlist>
	<listitem>
	  <para>Ели порт обращается к библиотеке Motif как
	    <literal>-lXm</literal> в своих файлах
	    <filename>Makefile</filename> или <filename>Imakefile</filename>,
	    просто подставьте вместо этих обращений
	    <literal>&dollar;{MOTIFLIB}</literal>.</para>
	</listitem>

	<listitem>
	  <para>Если порт использует <literal>XmClientLibs</literal> в своем
	    файле <filename>Imakefile</filename>, измените это обращение на
	    <literal>&dollar;{MOTIFLIB} &dollar;{XTOOLLIB}
	    &dollar;{XLIB}</literal>.</para>
	</listitem>
      </itemizedlist>

      <para>Заметьте, что переменная <makevar>MOTIFLIB</makevar> (как
	правило) раскрывается в <literal>-L/usr/X11R6/lib -lXm</literal> или
	<literal>/usr/X11R6/lib/libXm.a</literal>, так что нет нужды впереди
	добавлять <literal>-L</literal> или <literal>-l</literal>.</para>
    </sect1>
  </chapter>

  <chapter>
    <title>Шрифты для X11</title>

    <para>Если ваш порт устанавливает шрифты для системы X Window, поместите
      их в каталог
      <filename><makevar>X11BASE</makevar>/lib/X11/fonts/local</filename>.
      Этот каталог впервые появился в XFree86 release 3.3.3.  Если он не
      существует, то, будьте добры, создайте его и выведите сообщение,
      обращающее внимание пользователя на необходимость обновить XFree86 до
      версии 3.3.3 или более новой, или по крайней мере добавить этот каталог
      к маршруту поиска шрифтов в файле
      <filename>/etc/XF86Config</filename>.</para>
  </chapter>

  <chapter id="porting-info">
    <title>Файлы в формате info</title>

    <para>Новая версия texinfo (включенная в 2.2.2-RELEASE и выше), содержит
      утилиту с именем <command>install-info</command> для установки и
      удаления компонент в файле <filename>dir</filename>.  Если ваш порт
      устанавливает какие-либо документы в формате info, то, пожалуйста,
      следуйте этим инструкциям, чтобы ваш порт/пакадж корректно обновлял
      пользовательский файл
      <filename><makevar>PREFIX</makevar>/info/dir</filename>.	(Приносим
      извинения за размер этого раздела, но это необходимо для объединения
      всех файлов info вместе.	Если это делается правильно, то будет
      создан <emphasis>прекрасный</emphasis> список, так что прислушайтесь
      к моим советам!</para>

    <para>Во-первых, вот что вы (как создатель порта) должны знать</para>

    <screen>
&prompt.user; <userinput>install-info --help</userinput>
install-info [OPTION]... [INFO-FILE [DIR-FILE]]
  Install INFO-FILE in the Info directory file DIR-FILE.

Options:
--delete	  Delete existing entries in INFO-FILE;
		    don't insert any new entries.
 :
--entry=TEXT	  Insert TEXT as an Info directory entry.
 :
--section=SEC	  Put this file's entries in section SEC of the directory. :
    </screen>

    <note>
      <para>Эта программа на будет на самом деле
	<emphasis>устанавливать</emphasis> info-файлы; она просто добавляет
	или удаляет элементы списка в файле <filename>dir</filename>.</para>
    </note>

    <para>Далее приводится процедура, состоящая из семи шагов, для
      преобразования портов к использованию <command>install-info</command>.
      В качестве примера будет использоваться
      <filename>editors/emacs</filename>.</para>

    <procedure>
      <step>
	<para>Посмотрите в исходные тексты документов в формате texinfo и
	  измените их, вставив директивы <literal>@dircategory</literal> и
	  <literal>@direntry</literal> в файлы, в которых они отсутствуют.
	  Вот часть моего патча:</para>

	<programlisting>
--- ./man/vip.texi.org	Fri Jun 16 15:31:11 1995
+++ ./man/vip.texi	Tue May 20 01:28:33 1997
@@ -2,6 +2,10 @@

 @setfilename ../info/vip
 @settitle VIP
+@dircategory The Emacs editor and associated tools
+@direntry
+* VIP: (vip).		A VI-emulation for Emacs.
+@end direntry

 @iftex
 @finalout
 :
	</programlisting>

	<para>Формат должен быть для вас самоочевидным.  Многие авторы
	  оставляют среди исходных текстов файл <filename>dir</filename>,
	  содержащий все компоненты, которые вам нужны, так что проверьте
	  еще раз перед тем, как пытаться писать свои собственные.  Также
	  обязательно взгляните на порты, связанные с вашим и приведите в
	  соответствие имена разделов и формат компонент (мы рекомендуем,
	  чтобы все текстовые строки начинались с 4й позиции
	  табуляции).</para>

	<note>
	  <para>Заметьте, что вы можете указать только одну компоненту info
	    для файла из-за ошибки в работе утилиты
	    <command>install-info --delete</command>, которая удаляет только
	    первую компоненту, даже если вы укажете несколько компонент в
	    разделе <email>@direntry</email>.</para>
	</note>

	<para>Вы можете передать компоненты <literal>dir</literal> утилите
	  <command>install-info</command> в качестве аргументов
	  (<option>--section</option> и <option>--entry</option>), вместо
	  того, чтобы изменять исходный текст файлов texinfo,  Наверное,
	  это не подходит для портов, потому что вам нужно будет
	  продублировать информацию в <emphasis>трех</emphasis> местах
	  (<filename>Makefile</filename> и
	  <literal>@exec</literal>/<literal>@unexec</literal> в файле
	  <filename>pkg-plist</filename>; смотрите ниже).  Однако, если файлы
	  info имеют японскую (или другую многобайтовую кодировку), вам нужно
	  будет передать дополнительные аргументы команде
	  <command>install-info</command>, потому что
	  <command>makeinfo</command> не может работать с такими файлами
	  texinfo.  (Посмотрите файлы <filename>Makefile</filename> и
	  <filename>pkg-plist</filename> в каталоге
	  <filename>japanese/skk</filename> на предмет того, как это
	  сделать).</para>
      </step>

      <step>
	<para>Вернитесь обратно в каталог с портом, выполните команду
	  <command>make clean; make</command> и проверьте, что файлы info
	  были вновь сгенерированы из исходного текста texinfo.  Так как
	  исходные тексты texinfo являются более новыми файлами, чем файлы
	  в формате info, то они должны быть перестроены, когда вы выполняете
	  команду <command>make</command>; однако многие файлы
	  <filename>Makefile</filename> не включают правильные зависимости для
          генерации файлов info.  В случае <command>emacs</command> пришлось
	  изменить главный файл <filename>Makefile.in</filename>, чтобы
	  происходил переход в подкаталог <filename>man</filename> для
	  перегенерации файлов info.</para>

	<programlisting>
--- ./Makefile.in.org	Mon Aug 19 21:12:19 1996
+++ ./Makefile.in	Tue Apr 15 00:15:28 1997
@@ -184,7 +184,7 @@
 # Subdirectories to make recursively.	`lisp' is not included
 # because the compiled lisp files are part of the distribution
 # and you cannot remake them without installing Emacs first.
-SUBDIR = lib-src src
+SUBDIR = lib-src src man

 # The makefiles of the directories in $SUBDIR.
 SUBDIR_MAKEFILES = lib-src/Makefile man/Makefile src/Makefile oldXMenu/Makefile
 lwlib/Makefile
--- ./man/Makefile.in.org	Thu Jun 27 15:27:19 1996
+++ ./man/Makefile.in	Tue Apr 15 00:29:52 1997
@@ -66,6 +66,7 @@
 ${srcdir}/gnu1.texi \
 ${srcdir}/glossary.texi

+all: info
 info: $(INFO_TARGETS)

 dvi: $(DVI_TARGETS)
	</programlisting>

	<para>Второй блок изменений был необходим из-за того, что цель по
	  умолчанию в подкаталоге <filename>man</filename> называется
	  <maketarget>info</maketarget>, когда как главный файл
	  <filename>Makefile</filename> вызывает цель
	  <maketarget>all</maketarget>.  Была также удалена установка
	  информационного файла <filename>info</filename>, потому что в
	  каталоге <filename>/usr/share/info</filename> уже имеется файл с
	  таким же именем (этот патч здесь не показан).</para>
      </step>

      <step>
	<para>Если в файле <filename>Makefile</filename> есть процедура
	  установки файла <filename>dir</filename>, то удалите эту процедуру.
	  Вашему порту делать этого не надо.  Кроме того, удалите все
	  команды, которые будут пытаться творить что-то с файлом
	  <filename>dir</filename>.</para>

	<programlisting>
--- ./Makefile.in.org	Mon Aug 19 21:12:19 1996
+++ ./Makefile.in	Mon Apr 14 23:38:07 1997
@@ -368,14 +368,8 @@
	if [ `(cd ${srcdir}/info && /bin/pwd)` != `(cd ${infodir} && /bin/pwd)` ]; \
	then \
	  (cd ${infodir};  \
-	   if [ -f dir ]; then \
-	     if [ ! -f dir.old ]; then mv -f dir dir.old; \
-	     else mv -f dir dir.bak; fi; \
-	   fi; \
	   cd ${srcdir}/info ; \
-	   (cd $${thisdir}; ${INSTALL_DATA} ${srcdir}/info/dir ${infodir}/dir);
\
-	   (cd $${thisdir}; chmod a+r ${infodir}/dir); \
	   for f in ccmode* cl* dired-x* ediff* emacs* forms* gnus* info* message* mh-e* sc* vip*; do \
	     (cd $${thisdir}; \
	      ${INSTALL_DATA} ${srcdir}/info/$$f ${infodir}/$$f; \
	      chmod a+r ${infodir}/$$f); \
	</programlisting>
      </step>

      <step>
	<para>(Этот шаг необходим, если только вы модифицируете уже
	  существующий порт.)  Взгляните на файл
	  <filename>pkg-plist</filename> и удалите все, что пытается изменить
	  файл <filename>info/dir</filename>.  Это может быть также в файле
	  <filename>pkg-install</filename> или в каком-то другом файле, так
	  что ищите тщательно.</para>

	<programlisting>
Index: pkg-plist
===================================================================
RCS file: /usr/cvs/ports/editors/emacs/pkg-plist,v
retrieving revision 1.15
diff -u -r1.15 pkg-plist
--- pkg-plist	1997/03/04 08:04:00	1.15
+++ pkg-plist	1997/04/15 06:32:12
@@ -15,9 +15,6 @@
 man/man1/emacs.1.gz
 man/man1/etags.1.gz
 man/man1/ctags.1.gz
-@unexec cp %D/info/dir %D/info/dir.bak
-info/dir
-@unexec cp %D/info/dir.bak %D/info/dir
 info/cl
 info/cl-1
 info/cl-2
	</programlisting>
      </step>

      <step>
	<para>Добавьте цель <maketarget>post-install</maketarget> в файл
	  <filename>Makefile</filename> для вызова
	  <maketarget>install-info</maketarget> с именами установленных
	  файлов info в качестве параметров.  (Больше не нужно создавать
	  файл <filename>dir</filename> самостоятельно;  Программа
	  <command>install-info</command> автоматически создаст этот файл,
	  если он не существует.)</para>

	<programlisting>
Index: Makefile
===================================================================
RCS file: /usr/cvs/ports/editors/emacs/Makefile,v
retrieving revision 1.26
diff -u -r1.26 Makefile
--- Makefile	1996/11/19 13:14:40	1.26
+++ Makefile	1997/05/20 10:25:09	1.28
@@ -20,5 +20,8 @@
 post-install:
 .for file in emacs-19.34 emacsclient etags ctags b2m
	strip ${PREFIX}/bin/${file}
 .endfor
+.for info in emacs vip viper forms gnus mh-e cl sc dired-x ediff ccmode
+	install-info ${PREFIX}/info/${info} ${PREFIX}/info/dir
+.endfor

 .include &lt;bsd.port.mk&gt;
	</programlisting>
      </step>

      <step>
	<para>Отредактируйте файл <filename>pkg-plist</filename>, добавив
	  аналогичные директивы <literal>@exec</literal>, не забыв о
	  <literal>@unexec</literal> для
	  <command>pkg_delete</command>.</para>

	<programlisting>
Index: pkg/pkg-plist
===================================================================
RCS file: /usr/cvs/ports/editors/emacs/pkg-plist,v
retrieving revision 1.15
diff -u -r1.15 pkg-plist
--- pkg-plist	1997/03/04 08:04:00	1.15
+++ pkg-plist	1997/05/20 10:25:12	1.17
@@ -16,7 +14,14 @@
 man/man1/etags.1.gz
 man/man1/ctags.1.gz
+@unexec install-info --delete %D/info/emacs %D/info/dir
 :
+@unexec install-info --delete %D/info/ccmode %D/info/dir
 info/cl
 info/cl-1
@@ -87,6 +94,18 @@
 info/viper-3
 info/viper-4
+@exec install-info %D/info/emacs %D/info/dir
 :
+@exec install-info %D/info/ccmode %D/info/dir
 libexec/emacs/19.34/i386--freebsd/cvtmail
 libexec/emacs/19.34/i386--freebsd/digest-doc
	</programlisting>

	<note>
	  <para>Команды <literal>@unexec install-info --delete</literal>
	    указываются до собственно файлов info, чтобы они могли прочесть
	    файлы.  Кроме того, команды <literal>@exec install-info</literal>
	    следуют за файлами info и командой <literal>@exec</literal>,
	    которая создает файл <filename>dir</filename> file.</para>
	</note>
      </step>

      <step>
	<para><link linkend="porting-testing">Протестируйте</link> вашу
	  работу и полюбуйтесь ею.  <!-- smiley --><emphasis>:-)</emphasis>.
	  Проверяйте файл <filename>dir</filename> до и после выполнения
	  каждого шага.</para>
      </step>
    </procedure>
  </chapter>

<chapter>
  <title>Файлы <filename>pkg-<replaceable>*</replaceable></filename></title>

  <para>Есть несколько приёмов работы с файлами
    <filename>pkg-<replaceable>*</replaceable></filename>, которые мы ещё не
    описали, но они иногда могут быть очень кстати.</para>

    <sect1 id="porting-message">
      <title><filename>pkg-message</filename></title>

      <para>Если вам нужно вывести сообщение для человека, устанавливающего
	приложение, то вы можете поместить сообщение в файл
	<filename>pkg-message</filename>.  Эта возможность часто оказывается
	полезной для вывода дополнительных шагов установки, которые нужно
	предпринять после выполнения команды <command>pkg_add</command>, или
	для вывода информации о лицензировании.</para>

      <note>
	<para>Файл <filename>pkg-message</filename> не нужно добавлять в
	  <filename>pkg-plist</filename>.  И он не будет автоматически
	  выводиться, если пользователь использует порт, а не пакадж, так что
	  вы должны будете сами выводить его при выполнении цели
	  <maketarget>post-install</maketarget>.</para>
      </note>
    </sect1>

    <sect1>
      <title><filename>pkg-install</filename></title>

      <para>Если при установке бинарного пакаджа по команде
	<command>pkg_add</command> вашему порту нужно выполнить какие-то
	дополнительные действия или команды, то вы можете сделать это с
	помощью скрипта <filename>pkg-install</filename>.  Этот скрипт будет
	автоматически добавлен к пакаджу, и будет дважды запускаться по
	команде <command>pkg_add</command>. Первый раз в виде
	<literal>&dollar;{SH} pkg-install &dollar;{PKGNAME}
        PRE-INSTALL</literal>, а второй раз как <literal>&dollar;{SH} {PKGNAME}
        POST-INSTALL</literal>.
	Для распознавания того, в каком режиме запущен скрипт, можно
	использовать параметр <literal>&dollar;2</literal>.  Переменная
	окружения <envar>PKG_PREFIX</envar> будет принимать значение,
	соответствующее каталогу, в который устанавливается пакадж.
	Дополнительная информация находится на странице Справочника о
	команде &man.pkg.add.1;.</para>

      <note>
	<para>Этот скрипт не запускается автоматически, если вы
	  устанавливаете порт командой <command>make install</command>.
	  Если же вам действительно необходимо его запустить, то запустите
	  его явно из файла <filename>Makefile</filename> порта.</para>
      </note>
    </sect1>

    <sect1>
      <title><filename>pkg-req</filename></title>

      <para>Если вашему порту нужно определять, должен ли он устанавливаться
	или нет, то вы можете создать скрипт <quote>необходимости</quote>
	<filename>pkg-req</filename>.  Он будет вызван автоматически
	в момент установки/удаления для определения того, должны ли они
	реально выполняться.</para>

      <para>Скрипт будет запущен в процессе установки командой
        <command>pkg_add</command>, как <literal>pkg-req
	&dollar;{PKGNAME} INSTALL</literal>. В процессе удаления он
	будет запущен командой <command>pkg_delete</command>, как
	<literal>pkg-req &dollar;{PKGNAME} DEINSTALL</literal>.</para>
    </sect1>

    <sect1 id="porting-plist">
      <title>Изменение содержимого <filename>pkg-plist</filename> в зависимости
	от make-переменных</title>

      <para>Некоторые порты, в частности, порты p5-, должны менять содержимое
	своих файлов <filename>pkg-plist</filename> в зависимости от того, с
	какими параметрами они были отконфигурированы (или в зависимости от
	версии языка perl в случае портов p5-).  Чтобы облегчить этот
	процесс, любые вхождения ключевых слов <literal>%%OSREL%%</literal>,
	<literal>%%PERL_VER%%</literal> и <literal>%%PERL_VERSION%%</literal>
	в файле <filename>pkg-plist</filename> будут заменяться соответствующими
	значениями.  Значением <literal>%%OSREL%%</literal> является номер
	версии операционной системы (например, <literal>2.2.7</literal>).
	<literal>%%PERL_VERSION%%</literal> обозначает полный номер версия
	perl (например, <literal>5.00502</literal>), а
	<literal>%%PERL_VER%%</literal> - номер версии perl без номера
	патча (например, <literal>5.005</literal>).</para>

      <para>Если вам нужно сделать другие подстановки, вы можете указать в
	переменной <makevar>PLIST_SUB</makevar> список пар
	<literal><replaceable>VAR</replaceable>=<replaceable>VALUE</replaceable></literal>,
	и все вхождения <literal>%%<replaceable>VAR</replaceable>%%</literal>
	в файле <filename>pkg-plist</filename> будут заменяться на значение
	<replaceable>VALUE</replaceable>.</para>

      <para>Например, если у вас имеется порт, который устанавливает много
	файлов в каталог, зависящий от версии, вы можете задать нечто типа

	<programlisting>
OCTAVE_VERSION= 2.0.13
PLIST_SUB=	OCTAVE_VERSION=${OCTAVE_VERSION}
	</programlisting>

	в файле <filename>Makefile</filename> и использовать
	<literal>%%OCTAVE_VERSION%%</literal> везде, где нужно указать
	номер версии в файле <filename>pkg-plist</filename>.  Таким образом,
	при обновлении порта вам не нужно будет менять десятки (а в некоторых
	случаях и сотни) строк в файле <filename>pkg-plist</filename>.</para>

      <para>Эта подстановка (так же, как и добавление любых <link
	linkend="porting-manpages">страниц Справочника</link>) будет сделана
	между выполнением целей <maketarget>do-install</maketarget> и
	<maketarget>post-install</maketarget>, посредством чтения файла
	<makevar>PLIST</makevar> и записью в файл <makevar>TMPPLIST</makevar>
	(по умолчанию это файл
	<filename><makevar>WRKDIR</makevar>/.PLIST.mktmp</filename>).  Так
	что если ваш порт строит <makevar>PLIST</makevar> на лету, делайте
	это во время или до выполнения цели
	<maketarget>do-install</maketarget>.  Кроме того, если вашему порту
	требуется отредактировать получающийся файл, делайте это в цели
	<maketarget>post-install</maketarget> изменением файла
	<makevar>TMPPLIST</makevar>.</para>
    </sect1>

    <sect1>
      <title id="porting-pkgfiles">Изменение имён файлов
        <filename>pkg-<replaceable>*</replaceable></filename></title>

      <para>Все имена файлов
        <filename>pkg-<replaceable>*</replaceable></filename>
	определяются с помощью переменных, так что вы можете изменить их,
	если это нужно, в вашем файле <filename>Makefile</filename>.  Это
	особенно полезно, если вы используете одни и те же файлы
        <filename>pkg-<replaceable>*</replaceable></filename>
	совместно между несколькими портами или
	пишете в один из вышеперечисленных файлов (в главе о <link
	linkend="porting-wrkdir">записи в каталоги, отличные от
	<makevar>WRKDIR</makevar></link> объяснено, почему не рекомендуется
	осуществлять запись непосредственно в файлы
        <filename>pkg-<replaceable>*</replaceable></filename>.</para>

      <para>Вот список имён переменных и их значений по умолчанию.  (Значение
        <makevar>PKGDIR</makevar> по умолчанию равно
        <makevar>${MASTERDIR}</makevar>.)</para>

      <informaltable frame="none">
      <tgroup cols="2">
      <thead>
	<row>
	  <entry>Переменная</entry>
	  <entry>Значение по умолчанию</entry>
	</row>
      </thead>

      <tbody>
	<row>
	  <entry><makevar>COMMENT</makevar></entry>
	  <entry><literal>${PKGDIR}/pkg-comment</literal></entry>
	</row>

	<row>
	  <entry><makevar>DESCR</makevar></entry>
	  <entry><literal>${PKGDIR}/pkg-descr</literal></entry>
	</row>

	<row>
	  <entry><makevar>PLIST</makevar></entry>
	  <entry><literal>${PKGDIR}/pkg-plist</literal></entry>
	</row>

	<row>
	  <entry><makevar>PKGINSTALL</makevar></entry>
	  <entry><literal>${PKGDIR}/pkg-install</literal></entry>
	</row>

	<row>
	  <entry><makevar>PKGDEINSTALL</makevar></entry>
	  <entry><literal>${PKGDIR}/pkg-deinstall</literal></entry>
	</row>

	<row>
	  <entry><makevar>PKGREQ</makevar></entry>
	  <entry><literal>${PKGDIR}/pkg-req</literal></entry>
	</row>

	<row>
	  <entry><makevar>PKGMESSAGE</makevar></entry>
	  <entry><literal>${PKGDIR}/pkg-message</literal></entry>
	</row>
      </tbody>
      </tgroup>
      </informaltable>

      <para>Пожалуйста, изменяйте значения этих переменных, а не
	переопределяйте <makevar>PKG_ARGS</makevar>.  Если вы измените
	значение переменных <makevar>PKG_ARGS</makevar>, то эти файлы при
	установке из порта будут установлены в каталог
	<filename>/var/db/pkg</filename> некорректно.</para>
    </sect1>
  </chapter>

  <chapter>
    <title>Проблемы с лицензированием</title>

    <para>Некоторые программные пакеты имеют ограниченные лицензии или
      их использование в некоторых странах может оказаться (как нарушение
      патента).  То, что мы можем с этим сделать, сильно
      зависит от точных формулировок конкретных лицензионных
      соглашений.</para>

    <note>
      <para>На вас, как на человека, портирующего приложение, ложится
	обязанность прочесть лицензионные соглашения на программное
	обеспечение и удостовериться, что проект FreeBSD не будет являться
	их нарушителем, если будет заниматься распространением исходного
	кода или в откомпилированном виде по FTP или на компакт-дисках.  Если
	у вас возникли сомнения, то, пожалуйста, обратитесь в
	адрес &a.ports;.</para>
    </note>

    <para>Имеется две переменные, которые вы можете задать в Makefile
      в наиболее часто встречающихся ситуациях:</para>

    <orderedlist>
      <listitem>
	<para>Если порт имеет лицензию типа <quote>не продавать для
	  достижения прибыли</quote>, задайте в переменной
	  <makevar>NO_CDROM</makevar> строку, описывающую причину этого.  Мы
	  не будем помещать такие порты на компакт-диск во время выпуска
	  релиза.  Дистрибутивный файл и пакадж будут доступны по
	  FTP.</para>
      </listitem>

      <listitem>
	<para>Если получающийся пакадж должен строиться каждый раз уникальным
	  образом или получающийся бинарный пакадж не может распространяться
	  по лицензионным соображениям, то в переменной
	  <makevar>NO_PACKAGE</makevar> укажите строку, описывающую причину
	  этого.  Мы не будем помещать такие пакаджи ни на FTP-сервер, ни на
	  компакт-диск во время выпуска релиза.  Однако дистрибутивный файл
	  будет помещен на оба носителя.</para>
      </listitem>

      <listitem>
	<para>Если порт имеет юридические ограничения на использованию
	  (например, патентованное программное обеспечение) или имеет
	  лицензию <quote>не для коммерческого использования</quote>, то в
	  переменной <makevar>RESTRICTED</makevar> укажите строку,
	  описывающую причину этого.  Для таких портов ни дистрибутивный
	  файл, ни пакаджи не будут доступны даже с наших серверов
	  FTP.</para>
      </listitem>
    </orderedlist>

    <note>
      <para>Лицензия GNU General Public License (GPL), как версии 1, так и
	версии 2, для портов вызвать проблем не должна.</para>
    </note>

    <note>
      <para>Если вы являетесь коммиттером, обязательно обновите также файл
	<filename>ports/LEGAL</filename>.</para>
    </note>
  </chapter>

  <chapter id="port-upgrading">
    <title>Обновление</title>

    <para>Если вы заметите, что ваш порт устарел по сравнению с последней
      авторской версией, первым делом проверьте, что у вас находится самая
      последняя версия порта.  Вы можете найти их в каталоге
      <filename>ports/ports-current</filename> на зеркальных серверах FTP.
      Кроме того, вы можете использовать CVSup для поддержки актуальности
      всей Коллекции портов, как это описано в <ulink
      url="../handbook/synching.html#CVSUP-CONFIG">Руководстве</ulink>.</para>

    <para>Следующий шаг - это посылка письма человеку, ведущему этот порт
      (майнтайнеру), если он указан в файле <filename>Makefile</filename>
      порта.  Этот человек может уже работать над обновлением, или иметь
      причину не обновлять порт прямо сейчас (например, из-за проблем со
      стабильностью функционирования новой версии).</para>

    <para>Если ведущий попросил сделать обновление вас, или такой персоны не
      нашлось, то, пожалуйста, выполните обновление и пошлите рекурсивный
      diff-файл (подойдет как в унифицированном, так и контекстно-зависимом
      формате, однако коммиттеры предпочитают унифицированный формат)
      сравнения нового и старого каталогов нам (например, если каталог с
      модифицированным портом называется <filename>superedit</filename>,
      а оригинальный, совпадающий с находящимся в нашем дереве портов,
      <filename>superedit.bak</filename>, то пошлите нам результат выполнения
      команды <command>diff -ruN superedit.bak superedit</command>).
      Пожалуйста, проверьте результат работы этой команды, так, чтобы все
      изменения имели смысл.  Лучший способ послать нам diff-файл - включить
      его в посылку по команде &man.send-pr.1; (категория
      <literal>ports</literal>).  Будьте добры, в сообщении отметьте все
      добавленные или удаленные файлы, так как они будут непосредственно
      указаны CVS при выполнении операции коммита.  Если diff-файл имеет
      размер, превышающий 20КБ, сожмите его и обработайте утилитой uuencode;
      в противном случае просто включите его как есть в PR.</para>

    <note>
      <para>Повторяем еще раз - для посылки обновлений существующих портов
	используйте утилиту &man.diff.1;, а не &man.shar.1;!</para>
    </note>
  </chapter>

  <chapter>
    <title><anchor id="porting-dads">Что нужно, а что нельзя делать</title>

    <para>Вот список часто встречающихся действий, которые нужно и которые
      нельзя делать во время процесса портирования.  Вы должны проверять ваш
      порт по этому списку, и вы также можете проверять порты в базе
      сообщений PR, которые присланы другими людьми.  Присылайте любые
      комментарии о портах, которые вы проверили, так, как это описано в
      главе о <ulink
      url="../articles/contributing/contrib-how.html#CONTRIB-GENERAL">
      Сообщениях об ошибках и общих замечаниях</ulink>.  Проверка портов в
      базе сообщений PR позволит нам быстрее коммиттить их и удостовериться,
      что вы знаете, что делаете.</para>

    <sect1>
      <title>Удаление отладочной информации в бинарных файлах</title>

      <para>Удаляйте отладочную информацию из бинарных файлов.	Если в
	исходных текстах файлы уже усекается, это прекрасно; в противном
	случае вы должны добавить в цель <literal>post-install</literal>
	правило для выполнения этой операции самим. Вот пример:</para>

      <programlisting>
post-install:
	strip ${PREFIX}/bin/xdl
      </programlisting>

      <para>Для проверки того, удалена ли отладочная информация из
	установленного выполнимого файла, выполните команду &man.file.1;.
	Если утилита не выдаст строку <literal>not stripped</literal>, то
	файл уже обработан.</para>
    </sect1>

    <sect1>
      <title>Макросы INSTALL_*</title>

      <para>Используйте макросы, которые есть в файле
	<filename>bsd.port.mk</filename> для обеспечения правильных прав
	доступа и владения файлов в своих целях
	<maketarget>*-install</maketarget>.</para>

      <itemizedlist>
	<listitem>
	  <para><makevar>INSTALL_PROGRAM</makevar> - это команда для
	    установки бинарных выполнимых файлов.</para>
	</listitem>

	<listitem>
	  <para><makevar>INSTALL_SCRIPT</makevar> - это команда для установки
	    выполнимых скриптов.</para>
	</listitem>

	<listitem>
	  <para><makevar>INSTALL_DATA</makevar> - это команда для установки
	    совместно используемых файлов данных.</para>
	</listitem>

	<listitem>
	  <para><makevar>INSTALL_MAN</makevar> - это команда для установки
	    страниц Справочника и другой документации (никаких файлов она не
	    сжимает).</para>
	</listitem>
      </itemizedlist>

      <para>В основе работы этих макросов лежит команда
	<command>install</command> со всеми соответствующими флагами.
	Смотрите пример их использования ниже.</para>
    </sect1>

    <sect1 id="porting-wrkdir">
      <title><makevar>WRKDIR</makevar></title>

      <para>Не пишите ничего в файлы вне каталога <makevar>WRKDIR</makevar>.
	Каталог <makevar>WRKDIR</makevar> является единственным местом,
	которое гарантированно будет доступно для записи во время построения
	порта (обратитесь к главе о <ulink
        url="../handbook/ports-using.html#PORTS_CD">компиляции портов с
        компакт-диска</ulink> за
	примером построения портов из дерева, доступного только для чтения).
	Если вам нужно изменить какой-либо из файлов
        <filename>pkg-<replaceable>*</replaceable></filename>, сделайте это,
        <link linkend="porting-pkgfiles">переопределив переменную</link>, но не
	перезаписывая их.</para>
    </sect1>

    <sect1 id="porting-wrkdirprefix">
      <title><makevar>WRKDIRPREFIX</makevar></title>

      <para>Добейтесь того, чтобы ваш порт принимал во внимание значение
	переменной <makevar>WRKDIRPREFIX</makevar>.  Большинство портов об
	этом не заботятся.  В частности, если вы обращаетесь к каталогу
	<makevar>WRKDIR</makevar> другого порта, заметьте, что его правильным
	местоположением является
	<filename><makevar>WRKDIRPREFIX</makevar><makevar>PORTSDIR</makevar>/<replaceable>subdir</replaceable>/<replaceable>name</replaceable>/work</filename> not <filename><makevar>PORTSDIR</makevar>/<replaceable>subdir</replaceable>/work</filename>
	или <filename><makevar>.CURDIR</makevar>/../../<replaceable>subdir</replaceable>/<replaceable>name</replaceable>/work</filename>
	или что-то подобное.</para>

      <para>Кроме того, если вы сами задаете <makevar>WRKDIR</makevar>, то
	должны поставить перед ним знак
	<literal>&dollar;{WRKDIRPREFIX}&dollar;{.CURDIR}</literal>.</para>
    </sect1>

    <sect1 id="porting-versions">
      <title>Различение операционных систем и версий ОС</title>

      <para>Вы можете встретиться с кодом, который требует модификаций
	или условной компиляции в зависимости от того, с какой версией
	Unix он работает.  Если вам нудно сделать такие изменения в коде для
	условной компиляции, то вы должны делать изменения как можно
	более общими, чтобы мы могли перенести код на системы FreeBSD версий
	1.x, а также и на другие системы BSD, такие, как 4.4BSD от CSRG,
	BSD/386, 386BSD, NetBSD, и OpenBSD.</para>

      <para>Предпочтительным способом отделения кода для 4.3BSD/Reno (1990) и
	и более новых версий BSD является использование макроса
	<literal>BSD</literal>, определенного в файле
	<filename>&lt;sys/param.h&gt;</filename>.  Хорошо, если этот файл уже
	включен; если это не так, то добавьте такой код:</para>

      <programlisting>
#if (defined(__unix__) || defined(unix)) &amp;&amp; !defined(USG)
#include &lt;sys/param.h&gt;
#endif
      </programlisting>

      <para>в соответствующем месте файла <filename>.c</filename>.  Мы
	надеемся, что все системы, в которых определены эти две константы,
	имеют файл <filename>sys/param.h</filename>.  Если вы обнаружите
	систему, в которой это не так, мы хотим знать.	Пошлите, пожалуйста,
	письмо на адрес &a.ports;.</para>

      <para>Другим способом является использование для этого стиля GNU
	Autoconf:</para>

      <programlisting>
#ifdef HAVE_SYS_PARAM_H
#include &lt;sys/param.h&gt;
#endif
      </programlisting>

      <para>Не забудьте добавить <literal>-DHAVE_SYS_PARAM_H</literal> к
	<makevar>CFLAGS</makevar> в файле <filename>Makefile</filename>
	при использовании этого метода.</para>

      <para>Как только вы включите <filename>sys/param.h</filename>, то
	сможете воспользоваться следующим:</para>

      <programlisting>
#if (defined(BSD) &amp;&amp; (BSD &gt;= 199103))
      </programlisting>

      <para>для определения того, компилируется ли программа на основе кода
	Net2 версии 4.3 или более новой версии (например, FreeBSD 1.x,
	4.3/Reno, NetBSD 0.9, 386BSD, BSD/386 1.1 и ниже).</para>

      <para>Используйте:</para>

      <programlisting>
#if (defined(BSD) &amp;&amp; (BSD &gt;= 199306))
      </programlisting>

      <para>для определения того, компилируется ли программа на основе кода
	4.4 или более новой (например, FreeBSD 2.x, 4.4, NetBSD 1.0, BSD/386
	2.0 и выше).</para>

      <para>Значение макроса <literal>BSD</literal> равно
	<literal>199506</literal> для кода на основе 4.4BSD-Lite2.  Оно
	задано только для информационной целей.  Оно не должно использоваться
	для различия между версиями FreeBSD, основанными на коде 4.4-Lite
	и версиями, в которые включены изменения из 4.4-Lite2.	Вместо этого
	нужно использовать макрос <literal>__FreeBSD__</literal>.</para>

      <para>Реже используйте:</para>

      <itemizedlist>
	<listitem>
	  <para><literal>__FreeBSD__</literal> определен во всех версиях
	    FreeBSD.  Используйте его, если изменение, вносимое вами,
	    касается <emphasis>только</emphasis> FreeBSD.  Проблемы
	    портирования, такие, как использование
	    <literal>sys_errlist[]</literal> или
	    <function>strerror()</function> являются особенностями систем
	    BSD, а не FreeBSD.</para>
	</listitem>

	<listitem>
	  <para>Во FreeBSD 2.x, значение <literal>__FreeBSD__</literal>
	    определено как <literal>2</literal>.  В более ранних версиях оно
	    равно <literal>1</literal>.  В более поздних версиях это значение
	    увеличивается в соответствии со старшим номером версии
	    системы.</para>
	</listitem>

	<listitem>
	  <para>Если вам нужно отделить системы FreeBSD 1.x от систем
	    FreeBSD 2.x или 3.x, правильным способом, как правило, будет
	    использование макроса <literal>BSD</literal>, описанное выше.
	    Если это действительно изменение, специфичное для FreeBSD
	    (например, особая опция для динамической библиотеки при
	    использовании <command>ld</command>), то для распознавания
	    систем FreeBSD 2.x и более поздних нормальным будет использование
	    <literal>__FreeBSD__</literal> и
	    <literal>#if __FreeBSD__ &gt; 1</literal>.	Если вам нужно более
	    точное определение версий FreeBSD, начиная с 2.0-RELEASE, то
	    вы можете использовать следующее:</para>

	  <programlisting>
#if __FreeBSD__ &gt;= 2
#include &lt;osreldate.h&gt;
#    if __FreeBSD_version &gt;= 199504
	 /* 2.0.5+ release specific code here */
#    endif
#endif
	  </programlisting>

	  <informaltable frame="none">
	  <tgroup cols="2">
	  <thead>
	    <row>
	      <entry>Релиз</entry>
	      <entry><literal>__FreeBSD_version</literal></entry>
	    </row>
	  </thead>

	  <tbody>
	    <row>
	      <entry>2.0-RELEASE</entry>
	      <entry>119411</entry>
	    </row>

	    <row>
	      <entry>2.1-CURRENT</entry>
	      <entry>199501, 199503</entry>
	    </row>

	    <row>
	      <entry>2.0.5-RELEASE</entry>
	      <entry>199504</entry>
	    </row>

	    <row>
	      <entry>2.2-CURRENT до выхода 2.1</entry>
	      <entry>199508</entry>
	    </row>

	    <row>
	      <entry>2.1.0-RELEASE</entry>
	      <entry>199511</entry>
	    </row>

	    <row>
	      <entry>2.2-CURRENT до выхода 2.1.5</entry>
	      <entry>199512</entry>
	    </row>

	    <row>
	      <entry>2.1.5-RELEASE</entry>
	      <entry>199607</entry>
	    </row>

	    <row>
	      <entry>2.2-CURRENT до выхода 2.1.6</entry>
	      <entry>199608</entry>
	    </row>

	    <row>
	      <entry>2.1.6-RELEASE</entry>
	      <entry>199612</entry>
	    </row>

	    <row>
	      <entry>2.1.7-RELEASE</entry>
	      <entry>199612</entry>
	    </row>

	    <row>
	      <entry>2.2-RELEASE</entry>
	      <entry>220000</entry>
	    </row>

	    <row>
	      <entry>2.2.1-RELEASE</entry>
	      <entry>220000 (без изменений)</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после выхода 2.2.1-RELEASE</entry>
	      <entry>220000 (без изменений)</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после включения texinfo-3.9</entry>
	      <entry>221001</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после включения top</entry>
	      <entry>221002</entry>
	    </row>

	    <row>
	      <entry>2.2.2-RELEASE</entry>
	      <entry>222000</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после выхода 2.2.2-RELEASE</entry>
	      <entry>222001</entry>
	    </row>

	    <row>
	      <entry>2.2.5-RELEASE</entry>
	      <entry>225000</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после выхода 2.2.5-RELEASE</entry>
	      <entry>225001</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после появления ldconfig -R</entry>
	      <entry>225002</entry>
	    </row>

	    <row>
	      <entry>2.2.6-RELEASE</entry>
	      <entry>226000</entry>
	    </row>

	    <row>
	      <entry>2.2.7-RELEASE</entry>
	      <entry>227000</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после выхода 2.2.7-RELEASE</entry>
	      <entry>227001</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после изменения в &man.semctl.2;</entry>
	      <entry>227002</entry>
	    </row>

	    <row>
	      <entry>2.2.8-RELEASE</entry>
	      <entry>228000</entry>
	    </row>

	    <row>
	      <entry>2.2-STABLE после выхода 2.2.8-RELEASE</entry>
	      <entry>228001</entry>
	    </row>

	    <row>
	      <entry>3.0-CURRENT до изменения в &man.mount.2;</entry>
	      <entry>300000</entry>
	    </row>

	    <row>
	      <entry>3.0-CURRENT после изменения в &man.mount.2;</entry>
	      <entry>300001</entry>
	    </row>

	    <row>
	      <entry>3.0-CURRENT после изменения в &man.semctl.2;</entry>
	      <entry>300002</entry>
	    </row>

	    <row>
	      <entry>3.0-CURRENT после изменений в аргументах ioctl</entry>
	      <entry>300003</entry>
	    </row>

	    <row>
	      <entry>3.0-CURRENT после перехода на формат ELF</entry>
	      <entry>300004</entry>
	    </row>

	    <row>
	      <entry>3.0-RELEASE</entry>
	      <entry>300005</entry>
	    </row>

	    <row>
	      <entry>3.0-CURRENT после выхода 3.0-RELEASE</entry>
	      <entry>300006</entry>
	    </row>

	    <row>
	      <entry>3.0-STABLE после разбиения на ветки 3/4</entry>
	      <entry>300007</entry>
	    </row>

	    <row>
	      <entry>3.1-RELEASE</entry>
	      <entry>310000</entry>
	    </row>

	    <row>
	      <entry>3.1-STABLE после выхода 3.1-RELEASE</entry>
	      <entry>310001</entry>
	    </row>

	    <row>
	      <entry>3.1-STABLE после изменения в порядке следования
		конструкторов/деструкторов в C++</entry>
	      <entry>310002</entry>
	    </row>

	    <row>
	      <entry>3.2-RELEASE</entry>
	      <entry>320000</entry>
	    </row>

	    <row>
	      <entry>3.2-STABLE</entry>
	      <entry>320001</entry>
	    </row>

	    <row>
	      <entry>3.2-STABLE после несовместимых изменений в IPFW и
		сокетах</entry>
	      <entry>320002</entry>
	    </row>

	    <row>
	      <entry>3.3-RELEASE</entry>
	      <entry>330000</entry>
	    </row>

	    <row>
	      <entry>3.3-STABLE</entry>
	      <entry>330001</entry>
	    </row>

	    <row>
	      <entry>3.3-STABLE после добавления &man.mkstemp.3; в libc</entry>
	      <entry>330002</entry>
	    </row>

	    <row>
	      <entry>3.4-RELEASE</entry>
	      <entry>340000</entry>
	    </row>

	    <row>
	      <entry>3.4-STABLE</entry>
	      <entry>340001</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после появления ветки 3.4</entry>
	      <entry>400000</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после изменения в работе динамического
		компоновщика</entry>
	      <entry>400001</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после изменения в порядке следования
		конструкторов/деструкторов в C++</entry>
	      <entry>400002</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после появления функции &man.dladdr.3;</entry>
	      <entry>400003</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после исправления ошибки в работе функции
		__deregister_frame_info динамического компоновщика (а также
		4.0-CURRENT после интеграции EGCS 1.1.2)</entry>
	      <entry>400004</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после изменения интерфейса функции
                &man.suser.9; (а также 4.0-CURRENT после появления
                newbus)</entry>
	      <entry>400005</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после изменения в регистрации cdevsw</entry>
	      <entry>400006</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после добавления so_cred в проверки на
		уровне сокетов</entry>
	      <entry>400007</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после добавления обработчика системного
		вызова poll в libc_r</entry>
	      <entry>400008</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после перехода в ядре с типа
		<literal>dev_t</literal> на указатель
		<literal>struct specinfo</literal></entry>
	      <entry>400009</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после исправления дыры в безопасности
		&man.jail.2;</entry>
	      <entry>400010</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после изменения в типе данных
		<literal>sigset_t</literal></entry>
	      <entry>400011</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после перехода на компилятор
		GCC 2.95.2</entry>
	      <entry>400012</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после появления добавляемых обработчиков
		ioctl режима linux</entry>
	      <entry>400013</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после заимствования OpenSSL</entry>
	      <entry>400014</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после изменения в C++ ABI компилятора
		GCC 2.95.2 по умолчанию с -fvtable-thunks на
		-fno-vtable-thunks</entry>
	      <entry>400015</entry>
	    </row>

	    <row>
	      <entry>4.0-CURRENT после заимствования OpenSSH</entry>
	      <entry>400016</entry>
	    </row>

	    <row>
	      <entry>4.0-RELEASE</entry>
	      <entry>400017</entry>
	    </row>

	    <row>
	      <entry>4.0-STABLE после появления 4.0-RELEASE</entry>
	      <entry>400018</entry>
	    </row>

            <row>
              <entry>4.0-STABLE после интеграции кода библиотеки
                libxpg4 в libc.</entry>
              <entry>400020</entry>
            </row>

            <row>
              <entry>4.0-STABLE после обновления пакета Binutils до версии
                2.10.0, изменения в схеме пометки выполнимых файлов ELF и
                включения tcsh в качестве базового компонента.</entry>
              <entry>400021</entry>
            </row>

            <row>
              <entry>4.1-RELEASE</entry>
              <entry>410000</entry>
            </row>

            <row>
              <entry>4.1-STABLE после выхода 4.1-RELEASE</entry>
              <entry>410001</entry>
            </row>

            <row>
              <entry>4.1-STABLE после переноса функции &man.setproctitle.3; из
                библиотеки libutil в libc.</entry>
              <entry>410002</entry>
            </row>

            <row>
              <entry>4.1.1-RELEASE</entry>
              <entry>411000</entry>
            </row>

            <row>
              <entry>4.1.1-STABLE после выхода 4.1.1-RELEASE</entry>
              <entry>411001</entry>
            </row>

            <row>
              <entry>4.2-RELEASE</entry>
              <entry>420000</entry>
            </row>

            <row>
              <entry>4.2-STABLE после объединения libgcc.a и libgcc_r.a,
                а также соответствующих изменений в компоновке
                GCC.</entry>
              <entry>420001</entry>
            </row>

            <row>
              <entry>4.3-RELEASE</entry>
              <entry>430000</entry>
            </row>

            <row>
              <entry>4.3-STABLE после появления wint_t.</entry>
              <entry>430001</entry>
            </row>

            <row>
              <entry>4.3-STABLE после добавления API состояния электропитания
                PCI.</entry>
              <entry>430002</entry>
            </row>

            <row>
              <entry>4.4-RELEASE</entry>
              <entry>440000</entry>
            </row>

            <row>
              <entry>4.4-STABLE после добавления d_thread_t.</entry>
              <entry>440001</entry>
            </row>

            <row>
              <entry>4.4-STABLE после изменений в структуру для монтирования
                (это затрагивает KLD файловых систем).</entry>
              <entry>440002</entry>
            </row>

            <row>
              <entry>4.4-STABLE после импортирования пользовательских
                компонент smbfs.</entry>
              <entry>440003</entry>
            </row>

	    <row>
	      <entry>5.0-CURRENT</entry>
	      <entry>500000</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после добавления дополнительных полей в
                заголовке ELF и изменения метода пометки принадлежности
                к определённой системе для выполнимых файлов в формате
                ELF.</entry>
              <entry>500001</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после изменений в метаданных kld.</entry>
              <entry>500002</entry>
	    </row>

            <row>
              <entry>5.0-CURRENT после изменений buf/bio.</entry>
              <entry>500003</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после обновления binutils.</entry>
              <entry>500004</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после интеграции кода библиотеки libxpg4 в
                libc и появления интерфейса TASKQ.</entry>
              <entry>500005</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после добавления интерфейсов AGP.</entry>
              <entry>500006</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после обновления Perl до версии 5.6.0</entry>
              <entry>500007</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после обновления кода KAME до версии
                2000/07.</entry>
              <entry>500008</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после изменений в ether_ifattach() и
                ether_ifdetach().</entry>
              <entry>500009</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после возврата в настройках утилиты mtree,
                применяемых по умолчанию, обратно к оригинальным и добавления
                флага -L для перехода по символическим ссылкам.</entry>
              <entry>500010</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после изменения в API для kqueue.</entry>
              <entry>500011</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после перемещения &man.setproctitle.3; из
                библиотеки libutil в libc.</entry>
              <entry>500012</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после первого коммита SMPng.</entry>
              <entry>500013</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после переноса &lt;sys/select.h&gt; в
                &lt;sys/selinfo.h&gt;.</entry>
              <entry>500014</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после объединения libgcc.a и
                libgcc_r.a, а также соответствующих изменений в
                компоновке GCC.</entry>
              <entry>500015</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после изменения, позволяющего libc и
                libc_r быть скомпонованными вместе, что делает параметр
                -pthread ненужным.</entry>
              <entry>500016</entry>
            </row>

            <row>
	      <entry>5.0-CURRENT после перехода на использование
	        struct xucred вместо struct ucred для стабилизиции
	        экспортируемого API ядра для mountd и т.д.</entry>
              <entry>500017</entry>
            </row>

            <row>
	      <entry>5.0-CURRENT после добавления переменной make
	        CPUTYPE позволяющей контролировать специфичные
	        для CPU оптимизации.</entry>
              <entry>500018</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после переноса machine/ioctl_fd.h в
                sys/fdcio.h</entry>
              <entry>500019</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после изменения имен для локализации.</entry>
              <entry>500020</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после импортирования Bzip2.</entry>
              <entry>500021</entry>
            </row>

            <row>
              <entry>5.0-CURRENT с поддержкой SSE.</entry>
              <entry>500022</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после KSE Этап 2.</entry>
              <entry>500023</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после d_thread_t и переноса UUCP в
                порты.</entry>
              <entry>500024</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после изменения ABI из-за переноса передачи
                дескриптора и прав на 64-разрядные платформы.</entry>
              <entry>500025</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после перехода на использование по умолчанию
                XFree86 4 для построения пакаджей и после добавления в
                библиотеку libc новой функции strnstr().</entry>
              <entry>500026</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после добавления в библиотеку libc новой
                функции strcasestr().</entry>
              <entry>500027</entry>
            </row>

            <row>
              <entry>5.0-CURRENT после импортирования пользовательских
                компонент smbfs.</entry>
              <entry>500028</entry>
            </row>
	  </tbody>
	  </tgroup>
	  </informaltable>
	</listitem>
      </itemizedlist>

      <note>
	<para>Заметьте, что 2.2-STABLE иногда идентифицирует себя как
	  <quote>2.2.5-STABLE</quote> после 2.2.5-RELEASE.  Такой принцип
	  использовался год и месяц, но мы решили изменить его на более
	  однозначную систему нумерации старший/младший, начиная с версии
	  2.2.	Это объясняется тем, что параллельная разработка в нескольких
	  ветках делает непрактичным идентификацию релизов просто по их
	  реальным датам выпуска.  Если вы сейчас делаете порт, вам не стоит
	  заботиться о старых версиях -CURRENT; они перечислены здесь просто
	  в информационных целях.</para>
      </note>

      <para>Из сотен уже сделанных портов только в одном или двух случаях
	потребовалось использование <literal>__FreeBSD__</literal>.  Если
	старые порты использовали этот макрос не по назначению, вовсе не
	значит, что вам нужно поступать точно также.</para>
    </sect1>

    <sect1>
      <title>Написание чего-либо после
	<filename>bsd.port.mk</filename></title>

      <para>Не пишите ничего после строки
	<literal>.include &lt;bsd.port.mk&gt;</literal>.  Этой строки можно
	избежать, включив в где-то в середину вашего файла
	<filename>Makefile</filename> файл
	<filename>bsd.port.pre.mk</filename>, и
	файл <filename>bsd.port.post.mk</filename> в конец.</para>

      <note>
	<para>Вам нужно включить либо пару файлов
	  <filename>pre.mk</filename>/<filename>post.mk</filename>, либо
	  только <filename>bsd.port.mk</filename>; не смешивайте два этих
	  случая.</para>
      </note>

      <para>В файле <filename>bsd.port.pre.mk</filename> определяются лишь
	несколько переменных, которые могут быть использованы в тестах из
	файла <filename>Makefile</filename>, в файле
	<filename>bsd.port.post.mk</filename> заданы остальные.</para>

      <para>Вот некоторые важные переменные, определенные в файле
	<filename>bsd.port.pre.mk</filename> (это не полный список, для
	выяснения полного списка прочтите, пожалуйста, сам файл
	<filename>bsd.port.mk</filename>).</para>

      <informaltable frame="none">
      <tgroup cols="2">
      <thead>
	<row>
	  <entry>Переменная</entry>
	  <entry>Описание</entry>
	</row>
      </thead>

      <tbody>
	<row>
	  <entry><makevar>ARCH</makevar></entry>
	  <entry>Архитектура машины в виде, получаемом по команде
	    <command>uname -m</command> (например,
	    <literal>i386</literal>)</entry>
	</row>

	<row>
	  <entry><makevar>OPSYS</makevar></entry>
	  <entry>Тип операционной системы, получаемый по команде
	    <command>uname -s</command> (например,
	    <literal>FreeBSD</literal>)</entry>
	</row>

	<row>
	  <entry><makevar>OSREL</makevar></entry>
	  <entry>Версия релиза операционной системы (например,
	    <literal>2.1.5</literal> или <literal>2.2.7</literal>)</entry>
	</row>

	<row>
	  <entry><makevar>OSVERSION</makevar></entry>
	  <entry>Версия операционной системы в виде числа, то же, что и <link
	    linkend="porting-versions">
	    <literal>__FreeBSD_version</literal></link>.</entry>
	</row>

	<row>
	  <entry><makevar>PORTOBJFORMAT</makevar></entry>
	  <entry>Формат объектных файлов, используемых в системе
	    (<literal>aout</literal> или <literal>elf</literal>)</entry>
	</row>

	<row>
	  <entry><makevar>LOCALBASE</makevar></entry>
	  <entry>Корень дерева <quote>local</quote> (например,
	    <literal>/usr/local/</literal>)</entry>
	</row>

	<row>
	  <entry><makevar>X11BASE</makevar></entry>
	  <entry>Корень дерева <quote>X11</quote> (например,
	    <literal>/usr/X11R6</literal>)</entry>
	</row>

	<row>
	  <entry><makevar>PREFIX</makevar></entry>
	  <entry>Куда, собственно, устанавливается порт (обратитесь к <link
	    linkend="porting-prefix">
	    подробной информации о <makevar>PREFIX</makevar></link>).</entry>
	</row>
      </tbody>
      </tgroup>
      </informaltable>

      <note>
	<para>Если вы задаете переменные <makevar>USE_IMAKE</makevar>,
	  <makevar>USE_X_PREFIX</makevar>, или <makevar>MASTERDIR</makevar>,
	  то делайте это перед тем, как включать
	  <filename>bsd.port.pre.mk</filename>.</para>
      </note>

      <para>Вот несколько примеров того, что вы можете написать после
	<filename>bsd.port.pre.mk</filename>:</para>

      <programlisting>
# no need to compile lang/perl5 if perl5 is already in system
.if ${OSVERSION} > 300003
BROKEN= perl is in system
.endif

# only one shlib version number for ELF
.if ${PORTOBJFORMAT} == "elf"
TCL_LIB_FILE=  ${TCL_LIB}.${SHLIB_MAJOR}
.else
TCL_LIB_FILE=  ${TCL_LIB}.${SHLIB_MAJOR}.${SHLIB_MINOR}
.endif

# software already makes link for ELF, but not for a.out
post-install:
.if ${PORTOBJFORMAT} == "aout"
       ${LN} -sf liblinpack.so.1.0 ${PREFIX}/lib/liblinpack.so
.endif
      </programlisting>
    </sect1>

    <sect1>
      <title>Установка дополнительной документации</title>

      <para>Если с вашим программным обеспечением поставляется некоторая
	документация, отличающаяся от стандартных страниц Справочника и
	файлов info, которая, как вы думаете, будет полезна пользователям,
	установите ее в каталог
	<filename><makevar>PREFIX</makevar>/share/doc</filename>.  Это может
	быть сделано, как и в предыдущем разделе, в цели
	<maketarget>post-install</maketarget>.</para>

      <para>Создайте для вашего порта новый каталог.  Имя каталога должно
	соответствовать тому, что представляет из себя порт.  Обычно это
	означает <makevar>PORTNAME</makevar>.  Однако, если
	вы думаете, что пользователь захочет иметь разные версии порта,
	установленные одновременно, то вы можете использовать полное имя
	<makevar>PKGNAME</makevar>.</para>

      <para>Сделайте установку документации зависящей от переменной
	<makevar>NOPORTDOCS</makevar> для того, чтобы пользователи могли
	выключить это в файле <filename>/etc/make.conf</filename>, как
	здесь:</para>

      <programlisting>post-install:
.if !defined(NOPORTDOCS)
	${MKDIR} ${PREFIX}/share/doc/xv
	${INSTALL_MAN} ${WRKSRC}/docs/xvdocs.ps ${PREFIX}/share/doc/xv
.endif</programlisting>

      <para>Все устанавливаемые файлы с документацией и каталоги должны быть
        перечислены в файле <filename>pkg-plist</filename> с префиксом
        <literal>%%PORTDOCS%%</literal>, например:</para>

      <programlisting>%%PORTDOCS%%share/doc/pure-ftpd/AUTHORS
%%PORTDOCS%%share/doc/pure-ftpd/CONTACT
%%PORTDOCS%%@dirrm share/doc/pure-ftpd</programlisting>

      <para>Кроме того, вы можете использовать файл
	<filename>pkg-message</filename> для вывода сообщений во
	время установки.  За подробной информацией обратитесь к разделу
	об <link linkend="porting-message">использовании
	<filename>pkg-message</filename></link>.</para>

      <note>
	<para>Файл <filename>pkg-message</filename> не нужно добавлять в
	  <filename>pkg-plist</filename>.</para>
      </note>
    </sect1>

    <sect1>
      <title><makevar>DIST_SUBDIR</makevar></title>

      <para>Не позволяйте вашему порту засорять
	<filename>/usr/ports/distfiles</filename>.  Если вашему порту
	требуется сгрузить много файлов, или он содержит имя файла,
	могущее вызвать конфликты с другими портами (например,
	<filename>Makefile</filename>), то укажите в переменной
	<makevar>DIST_SUBDIR</makevar> имя порта (должны подойти
        <literal>${PORTNAME}</literal> или
        <literal>${PKGNAMEPREFIX}${PORTNAME}</literal>).  Это изменит значение
	переменной <makevar>DISTDIR</makevar> со значения по умолчанию
	<filename>/usr/ports/distfiles</filename> к значению
	<filename>/usr/ports/distfiles/<makevar>DIST_SUBDIR</makevar></filename>,
	и в результате все, что требуется для порта, будет помещено в этот
	подкаталог.</para>

      <para>Он заглянет также в подкаталог с тем же именем на
	основном резервном сервере <filename>ftp.FreeBSD.org</filename>.
	(Явное задание переменной <makevar>DISTDIR</makevar> в вашем файле
	<makevar>Makefile</makevar> этого не сделает, так что, пожалуйста,
	воспользуйтесь <makevar>DIST_SUBDIR</makevar>.)</para>

      <note>
	<para>Это не коснется тех сайтов <makevar>MASTER_SITES</makevar>,
	  которые вы указали в вашем файле Makefile.</para>
      </note>
    </sect1>

    <sect1>
      <title>Информация о пакадже</title>

      <para>Дайте информацию о пакадже, то есть
	<filename>pkg-comment</filename>, <filename>pkg-descr</filename> и
	<filename>pkg-plist</filename>.</para>

      <note>
	<para>Заметьте, что эти файлы теперь используются не только в
	  системе пакаджей, и они <emphasis>обязательны</emphasis>, даже если
	  определена переменная <makevar>NO_PACKAGE</makevar>.</para>
      </note>
    </sect1>

    <sect1>
      <title>Строки RCS</title>

      <para>Не помещайте строки RCS в патчи.  CVS будет изменять их при
	помещении файлов в дерево портов, и когда мы будем их оттуда
	извлекать, они будут уже другие, поэтому применение патчей
	окончится неудачей.  Строчки RCS предваряются знаком доллара
	(<literal>&dollar;</literal>), и обычно начинаются с
	<literal>&dollar;Id</literal> или
	<literal>&dollar;RCS</literal>.</para>
    </sect1>

    <sect1>
      <title>Рекурсивные файлы diff</title>

      <para>Использование параметра рекурсии (<option>-r</option>) с командой
	<command>diff</command> для генерации патчей - это хорошо, но все же,
	пожалуйста, смотрите на получающиеся патчи, чтобы убедиться в
	отсутствии ненужного мусора.  В частности, diff между двумя
	резервными копиями файлов, файлы <filename>Makefile</filename>, когда
	как порт использует <command>Imake</command> или
	GNU-версию программы <command>configure</command>, и так далее,
	не нужны, и должны быть удалены.  Если вы отредактировали файл
	<filename>configure.in</filename> и запустили
	<command>autoconf</command> для перегенерации
	<command>configure</command>, не нужно включать файлы diff для
	<command>configure</command> (они частенько вырастают до нескольких
	тысяч строк!); задайте <literal>USE_AUTOCONF=yes</literal> и
	включите дифф-файл для <filename>configure.in</filename>.</para>

      <para>Кроме того, если вы удаляете файл, то это можно сделать и в цели
	<maketarget>post-extract</maketarget>, а не внутри патча.  Как только
	вы будете удовлетворены получающимся дифф-файлом, разбейте его на
	несколько по одному патчу на отдельный файл.</para>
    </sect1>

    <sect1 id="porting-prefix">
      <title><makevar>PREFIX</makevar></title>

      <para>Попытайтесь сделать так, чтобы установка вашего порта
	осуществлялась относительно каталога <makevar>PREFIX</makevar>.
	(Значение этой переменной будет установлено в
	<makevar>LOCALBASE</makevar> (по умолчанию
	<filename>/usr/local</filename>), если только не заданы переменные
	<makevar>USE_X_PREFIX</makevar> или <makevar>USE_IMAKE</makevar>,
	в случае чего он будет принят равным <makevar>X11BASE</makevar>
	(по умолчанию <filename>/usr/X11R6</filename>).)</para>

      <para>Отсутствие явного указания <filename>/usr/local</filename> или
	<filename>/usr/X11R6</filename> нигде в исходном коде сделает порт
	гораздо более гибким и способным удовлетворить потребности других
	серверов.  Для портов, которые используют X, это происходит
	автоматически; в противном случае зачастую это может быть сделано
	простой заменой строк <filename>/usr/local</filename> (или
	<filename>/usr/X11R6</filename> для портов X, не использующих imake)
	в различных скриптах/файлах Makefile порта на чтение
	<makevar>PREFIX</makevar>, так как эта переменная автоматически
	передается далее на каждом этапе построения и установки.</para>

      <para>Проверьте, что ваше приложение не устанавливает чего-либо в
        каталог <filename>/usr/local</filename> вместо
        <makevar>PREFIX</makevar>.  Это можно быстро проверить следующим
        образом:</para>

      <screen>
&prompt.root; <userinput>make clean; make package PREFIX=/var/tmp/<replaceable>p
ort-name</replaceable></userinput>
      </screen>

      <para>Если что-то было установлено за пределами
        <makevar>PREFIX</makevar>, то процесс создания пакаджа сообщит об
        отсутствии файлов.</para>

      <!-- XXX This paragraph is confusing and poorly indented. -->
      <para>Здесь не проверяется ни наличие внешних ссылок, ни корректность
        использования <makevar>LOCALBASE</makevar> в качестве ссылки на
        файлы из других портов.  Проверка установки в каталог
        <filename>/var/tmp/<replaceable>port-name</replaceable></filename>
        делает это.</para>

      <para>Не задавайте переменную <makevar>USE_X_PREFIX</makevar> до тех
	пор, пока она на самом деле не понадобится для порта (то есть он
	будет скомпонован с библиотеками X или нужно будет обращаться к
	файлам из <makevar>X11BASE</makevar>).</para>

      <para>Переменная <makevar>PREFIX</makevar> может быть переназначена в
	вашем файле <filename>Makefile</filename> или в окружении
	пользователя.  Однако строго не рекомендуется отдельным портам
	устанавливать эту переменную явно в файле
	<filename>Makefiles</filename>.</para>

      <para>Кроме того, обратитесь к программам/файлам из других портов с
	переменными, перечисленными выше, без указания явных маршрутов.
	Например, если ваш порт требует, чтобы макро <literal>PAGER</literal>
	являлся полным путем утилиты <command>less</command>, используйте
	флаг компилятора:

	<programlisting>
-DPAGER=\"&dollar;{PREFIX}/bin/less\"
	</programlisting>

	или

	<programlisting>
-DPAGER=\"&dollar;{LOCALBASE}/bin/less\"
	</programlisting>

	если это порт X, вместо того, чтобы задавать
	<literal>-DPAGER=\"/usr/local/bin/less\"</literal>.  Этот способ
	имеет больше шансов на работу, если системный администратор
	переместил все дерево `/usr/local' куда-то в другое место.</para>
    </sect1>

    <sect1>
      <title>Подкаталоги</title>

      <para>Попробуйте поместить все файлы порта в правильных подкаталогах
	каталога <makevar>PREFIX</makevar>.  Некоторые порты игнорируют все
	установки и помещают все в подкаталог с именем порта, что
	неправильно.  Также многие порты помещают все, кроме бинарных файлов,
	файлов заголовков и страниц Справочника, в подкаталог каталога
	<filename>lib</filename>, что не очень хорошо соответствует парадигме
	BSD.  Многие файлы должны быть перемещены в одно из следующих
	местоположений: <filename>etc</filename>
	(настроечные/конфигурационные файлы), <filename>libexec</filename>
	(выполнимые файлы, запускаемые из других программ),
	<filename>sbin</filename> (исполнимые файлы для
	администраторов/менеджеров системы), <filename>info</filename>
	(документация в формате info для просмотрщика info) или
	<filename>share</filename> (независимые от архитектуры файлы).
	Обратитесь к &man.hier.7; для прояснения деталей, правила,
	покрывающие <filename>/usr</filename>, достаточно хорошо подходят
	также и к <filename>/usr/local</filename>.  Исключением являются
	порты, имеющие дело с <quote>новостями</quote> USENET.  Они могут
	использовать каталог
	<filename><makevar>PREFIX</makevar>/news</filename> для установки
	своих файлов.</para>
    </sect1>

    <sect1 id="porting-cleaning">
      <title>Очистка пустых каталогов</title>

      <para>Заставьте ваш порты очищать за собой при удалении.	Обычно это
	достигается добавлением строк <literal>@dirrm</literal> для всех
	каталогов, которые создаются этим портом.  Вам нужно удалить
	подкаталоги до того, как вы сможете удалить родительские
	каталоги.</para>

      <programlisting>
 :
lib/X11/oneko/pixmaps/cat.xpm
lib/X11/oneko/sounds/cat.au
 :
@dirrm lib/X11/oneko/pixmaps
@dirrm lib/X11/oneko/sounds
@dirrm lib/X11/oneko
      </programlisting>

      <para>Однако иногда <literal>@dirrm</literal> будет выдавать ошибку,
	потому что другие порты тоже используют тот же самый подкаталог.  Вы
	можете вызвать команду <command>rmdir</command> из
	<literal>@unexec</literal> для удаления без выдачи предупреждений
	только пустого каталога.</para>

      <programlisting>
@unexec rmdir %D/share/doc/gimp 2>/dev/null || true
      </programlisting>

      <para>Эта команда не выведет никаких сообщений об ошибках и не вызовет
	аварийного завершения работы <command>pkg_delete</command>, даже если
	каталог <filename><makevar>PREFIX</makevar>/share/doc/gimp</filename>
	не пуст из-за того, что другие порты установили сюда какие-то
	файлы.</para>
    </sect1>

    <sect1>
      <title>Идентификаторы UID</title>

      <para>Если вашему порты требуется наличие некоторого пользователя в
	системе, на которую он устанавливается, пусть скрипт
	<filename>pkg-install</filename> вызовет команду
	<command>pw</command> для его автоматического создания.  Посмотрите
	для примера на <filename>net/cvsup-mirror</filename>.</para>

      <para>Если ваш порт должен использовать тот же самый идентификатор
	пользователя или группы при установке двоичного пакаджа, который был
	при компиляции, то вы должны выбрать свободный UID в диапазоне от 50
	до 999 и зарегистрировать его ниже.  Взгляните для примера на
	<filename>japanese/Wnn</filename>.</para>

      <para>Проверьте, что вы не используете UID, уже используемый системой
	или другими портами.  Вот текущий список UID между 50 и 999.</para>

      <programlisting>majordom:*:54:54:Majordomo Pseudo User:/usr/local/majordomo:/nonexistent
cyrus:*:60:60:the cyrus mail server:/nonexistent:/nonexistent
gnats:*:61:1:GNATS database owner:/usr/local/share/gnats/gnats-db:/bin/sh
uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/libexec/uucp/uucico
xten:*:67:67:X-10 daemon:/usr/local/xten:/nonexistent
pop:*:68:6:Post Office Owner (popper):/nonexistent:/sbin/nologin
wnn:*:69:7:Wnn:/nonexistent:/nonexistent
ifmail:*:70:66:Ifmail user:/nonexistent:/nonexistent
pgsql:*:70:70:PostgreSQL pseudo-user:/usr/local/pgsql:/bin/sh
ircd:*:72:72:IRCd hybrid:/nonexistent:/nonexistent
www:*:80:80:World Wide Web Owner:/nonexistent:/sbin/nologin
alias:*:81:81:QMail user:/var/qmail/alias:/nonexistent
qmaill:*:83:81:QMail user:/var/qmail:/nonexistent
qmaild:*:82:81:QMail user:/var/qmail:/nonexistent
qmailq:*:85:82:QMail user:/var/qmail:/nonexistent
qmails:*:87:82:QMail user:/var/qmail:/nonexistent
qmailp:*:84:81:QMail user:/var/qmail:/nonexistent
qmailr:*:86:82:QMail user:/var/qmail:/nonexistent
msql:*:87:87:mSQL-2 pseudo-user:/var/db/msqldb:/bin/sh
mysql:*:88:88:MySQL Daemon:/var/db/mysql:/sbin/nologin
vpopmail:*:89:89::0:0:User &:/usr/local/vpopmail:/nonexistent
smmsp:*:90:90:Sendmail Queue:/nonexistent:/nonexistent
drweb:*:426:426:Dr.Web Mail Scanner:/nonexistent:/sbin/nologin</programlisting>

      <para>Пожалуйста, при посылке нового (или обновлении старого) порта
	напишите замечание, что резервируете новый UID или GID в этом
	диапазоне.  Это позволит нам держать список зарезервированных
	идентификаторов в актуальном состоянии.</para>
    </sect1>

    <sect1>
      <title>Поступайте разумно</title>

      <para>Файл <filename>Makefile</filename> должен выполнять действия
	просто и небеспричинно.  Если вы можете сделать что-то на несколько
	строк короче или более читабельно, сделайте это.  В качестве примеров
	можно привести использование конструкций <literal>.if</literal>
	утилиты make вместо соответствующей конструкции <literal>if</literal>
	командного процессора, ненужность переопределения цели
	<maketarget>do-extract</maketarget> при возможности переопределения
	<makevar>EXTRACT*</makevar> и использование
	<makevar>GNU_CONFIGURE</makevar> вместо
	<literal>CONFIGURE_ARGS+= --prefix=&dollar;{PREFIX}</literal>.</para>
    </sect1>

    <sect1>
      <title>Использование <makevar>CFLAGS</makevar></title>

      <para>Порт должен принимать во внимание переменную
	<makevar>CFLAGS</makevar>.  Если он этого не делает, то, пожалуйста,
	добавьте в файл <filename>Makefile</filename> строчку
	<literal>NO_PACKAGE=ignores cflags</literal>.</para>

      <para>Пример файла <filename>Makefile</filename>, в котором принимается
        во внимание переменная <makevar>CFLAGS</makevar>, приводится далее.
        Отметьте употребление символов <makevar>+=</makevar>:</para>

      <programlisting>
CFLAGS += -Wall -Werror
      </programlisting>

      <para>А вот пример, в котором не учитывается значение переменной
        <makevar>CFLAGS</makevar>:</para>

      <programlisting>
CFLAGS = -Wall -Werror
      </programlisting>

      <para>В системе FreeBSD переменная <makevar>CFLAGS</makevar> определена
        в файле <filename>/etc/make.conf</filename>.  В первом примере к
        переменной <makevar>CFLAGS</makevar> добавляются дополнительные флаги,
        при этом сохраняются все определения, данные ранее на уровне системы.
        Во втором примере всё, что было задано ранее, игнорируется.</para>
    </sect1>

    <sect1>
      <title>Конфигурационные файлы</title>

      <para>Если для работы порта требуются наличие некоторых
	конфигурационных файлов в каталоге
	<filename><makevar>PREFIX</makevar>/etc</filename>,
	<emphasis>не</emphasis> просто установите их и перечислите в файле
	<filename>pkg-plist</filename>.  Это приведёт к тому, что по команде
	<command>pkg_delete</command> или при новой установке файлы,
	тщательно отредактированные и настроенные пользователем, будут
	уничтожены.</para>

      <para>Вместо этого установите файлы с примерами с неким расширением
	(<filename><replaceable>filename</replaceable>.sample</filename>
	подойдет) и выведите <link
	linkend="porting-message">сообщение</link>, указывающее на то, чтобы
	пользователь скопировал и отредактировал файл перед тем, как работать
	с программным обеспечением.</para>
    </sect1>

    <sect1>
      <title>Утилита portlint</title>

      <para>Проверяйте вашу работу с помощью утилиты <link
	linkend="porting-portlint"><command>portlint</command></link>
	перед тем, как послать ее нам или выполнить коммитт.</para>
    </sect1>

    <sect1>
      <title>Пожелания</title>

      <para>Посылайте подходящие изменения/патчи авторам/сопровождающему
	для включения в следующий релиз.  Это только сделает вашу работу
	гораздо легче при выходе следующего релиза.</para>
    </sect1>

    <sect1>
      <title><filename>README.html</filename></title>

      <para>Не включайте сюда файл <filename>README.html</filename>.  Этот файл
        не является частью дерева cvs, и он генерируется при помощи команды
        <command>make readme</command>.</para>
    </sect1>

    <sect1>
      <title>Разное</title>

      <para>Файлы <filename>pkg-comment</filename>,
	<filename>pkg-descr</filename> и <filename>pkg-plist</filename> вы
	должны проверять дважды.  Если вы просматриваете порт и думаете,
	что его можно переформулировать иначе, сделайте это.</para>

      <para>Пожалуйста, не создавайте дополнительных копий лицензии GNU
	General Public License в нашей системе.</para>

      <para>Будьте внимательны с юридическими вопросами!  Не делайте из нас
	нелегальных распространителей ПО!</para>
    </sect1>

    <sect1>
      <title>Если вы испытываете затруднения&hellip;</title>

      <para>Посмотрите существующие примеры и файл
	<filename>bsd.port.mk</filename> перед тем, как задавать нам вопросы!
	<!-- smiley --><emphasis>;-)</emphasis></para>

      <para>Задавайте нам вопросы, если у вас появились проблемы!  Не бейтесь
	головой об стену! <!-- smiley --><emphasis>:-)</emphasis></para>
    </sect1>
  </chapter>

  <chapter id="porting-samplem">
    <title>Примерный <filename>Makefile</filename></title>

    <para>Вот примерный <filename>Makefile</filename>, который можно
      использовать при создании нового порта.  Обязательно удалите все
      дополнительные комментарии (те, которые в скобках)!</para>

    <para>Вам рекомендуется следовать этому формату (соблюдая порядок
      следования переменных, пустые строки между разделами, и так далее).
      Этот формат разработан для того, чтобы важная информация была легко
      найдена.	Мы рекомендуем вам воспользоваться утилитой <link
      linkend="porting-portlint">portlint</link> для проверки файла
      <filename>Makefile</filename>.</para>

    <programlisting>
[заголовок...просто чтобы нам было легче идентифицировать порт.]
# New ports collection makefile for:   xdvi
[строчка "version required" необходима только тогда, когда переменная
PORTVERSION недостаточно конкретна для описания порта.]
# Date created: 	       26 May 1995
[Это человек, который сделал первоначальный порт для FreeBSD, в частности,
тот, кто создал первую версию этого файла Makefile.  Запомните, что позже
при обновлении порта эта строка меняться не должна.]
# Whom: 		       Satoshi Asami &lt;asami@FreeBSD.org&gt;
#
# &dollar;FreeBSD&dollar;
[ ^^^^^^^^^ Эта строка будет автоматически заменена со строчкой RCS ID
системой CVS при выполнении операции коммитта в наше хранилище.  При
обновлении порта не приводите эту строку обратно к виду
"&dollar;FreeBSD&dollar;".  CVS сделает все автоматически.]
#

[секция описания собственно порта и основного сервера - сначала всегда
 PORTNAME и PORTVERSIONA, за ним следует CATEGORIES, а затем
 MASTER_SITES, за которым может идти MASTER_SITE_SUBDIR.
 PKGNAMEPREFIX и PKGNAMESUFFIX, если они нужны, следуют за ними.
 Затем следует DISTNAME, EXTRACT_SUFX и/или DISTFILES, а потом, если это нужно,
 EXTRACT_ONLY.]
PORTNAME=      xdvi
PORTVERSION=   18.2.]
CATEGORIES=    print
[не забывайте лидирующий слэш ("/")!
 если вы не используете макросы MASTER_SITE_*]
MASTER_SITES=  ${MASTER_SITE_XCONTRIB}
MASTER_SITE_SUBDIR= applications
PKGNAMEPREFIX= ja-
DISTNAME=      xdvi-pl18
[задайте это, если исходный код поставляется не в виде
 стандартного файла ".tar.gz"]
EXTRACT_SUFX=  .tar.Z

[секция патчей -- может быть пустой]
PATCH_SITES=   ftp://ftp.sra.co.jp/pub/X11/japanese/
PATCHFILES=    xdvi-18.patch1.gz xdvi-18.patch2.gz

[сопровождающий; *обязательное поле*!  Это человек (предпочтительно с
 привилегиями на операцию коммитта), с которым может связаться пользователь
 для получения ответов на вопросы и посылки сообщений об ошибках - этот
 человек должен быть создателем порта или кем-то, кто может передать
 вопросы создателю порта.  Если вы на самом деле не хотите указывать здесь
 свой адрес, задайте здесь "ports@FreeBSD.org".]
MAINTAINER=    asami@FreeBSD.org

[зависимости -- могут быть пустыми]
RUN_DEPENDS=   gs:${PORTSDIR}/print/ghostscript
LIB_DEPENDS=   Xpm.5:${PORTSDIR}/graphics/xpm

[этот раздел для остальных стандартных переменных из bsd.port.mk, кроме
 тех, что перечислены выше]
[Если порт задает вопросы во время этапов настройки, построения,
 установки...]
IS_INTERACTIVE=        yes
[Если распаковка происходит в каталог, отличных от ${DISTNAME}...]
WRKSRC= 	       ${WRKDIR}/xdvi-new
[Если патчи делались не относительно ${WRKSRC}, вам, может быть, не
 придется изменять эту переменную]
PATCH_DIST_STRIP=      -p1
[Если порт требует скрипта "configure", генеруемого GNU-версией программы
 autoconf]
GNU_CONFIGURE= yes
[Если для построения порту требуется GNU-версия утилиты make, а не
 /usr/bin/make...]
USE_GMAKE=     yes
[Если это приложение X и требует запуска "xmkmf -a"...]
USE_IMAKE=     yes
[и так далее]

[В правилах ниже используются нестандартные переменные]
MY_FAVORITE_RESPONSE=  "yeah, right"

[теперь специальные правила, в порядке их вызова]
pre-fetch:
	я что-то выкачиваю, точно

post-patch:
	мне кое-что сделать после применения патча, великолепно

pre-install:
	и потом еще кое-что перед установкой, ого

[и, наконец, эпилог]
.include &lt;bsd.port.mk&gt;
    </programlisting>
  </chapter>

  <chapter id="porting-autoplist">
    <title>Автоматическое создание списка упаковки</title>

    <para>Первым делом убедитесь, что ваш порт практически полностью
      завершен, осталось только создать <filename>pkg-plist</filename>.
      Создайте пустой файл <filename>pkg-plist</filename>.</para>

    <screen>&prompt.root; <userinput>touch pkg-plist</userinput></screen>

    <para>Затем создайте новый набор каталогов, в которые может быть
      установлен ваш порт, и установите все зависимости.</para>

    <screen>&prompt.root; <userinput>mtree -U -f /etc/mtree/BSD.local.dist -d -e -p /var/tmp/<replaceable>port-name</replaceable></userinput>
&prompt.root; <userinput>make depends PREFIX=/var/tmp/<replaceable>port-name</replaceable></userinput></screen>

    <para>Сохраните структуру каталогов в новом файле.</para>

    <screen>&prompt.root; <userinput>(cd /var/tmp/<replaceable>port-name</replaceable> && find -d * -type d) &gt; OLD-DIRS</userinput></screen>

    <para>Если ваш порт принимает во внимание <makevar>PREFIX</makevar> (а он
      должен это делать), то тогда вы можете установить порт и создать список
      упаковки.</para>

    <screen>&prompt.root; <userinput>make install PREFIX=/var/tmp/<replaceable>port-name</replaceable></userinput>
&prompt.root; <userinput>(cd /var/tmp/<replaceable>port-name</replaceable> && find -d * \! -type d) &gt; pkg-plist</userinput></screen>

    <para>Кроме того, в список упаковки вы должны добавить все вновь
      созданные каталоги.</para>

    <screen>&prompt.root; <userinput>(cd /var/tmp/<replaceable>port-name && find -d * -type d) | comm -13 OLD-DIRS - | sed -e 's#^#@dirrm #' &gt;&gt; pkg-plist</replaceable></userinput></screen>

    <para>И наконец, вам нужно вручную отшлифовать список упаковки; его
      создание автоматизировано <emphasis>не полностью</emphasis>.  Страницы
      справочной системы должны быть перечислены в файле
      <filename>Makefile</filename> порта в переменных
      <makevar>MAN<replaceable>n</replaceable></makevar>, а не в списке
      упаковки.  Пользовательские конфигурационные файлы должны быть удалены
      или быть установлены как
      <filename><replaceable>filename</replaceable>.sample</filename>.
      Файл <filename>info/dir</filename> включать в список не нужно, но
      должны быть добавлены соответствующие строчки
      <filename>install-info</filename>, так, как это описано в разделе о <link
      linkend="porting-info">файлах в формате info</link>.  Все
      библиотеки, устанавливаемые портом, должны быть перечислены так, как
      это описано в разделе о <link
      linkend="porting-shlibs">динамических библиотеках</link>.</para>
  </chapter>


  <chapter id="porting-pkgname">
    <title>Имена пакаджей</title>

    <para>Далее описаны некоторые соглашения, которым вы должны следовать
      в именовании ваших пакаджей.  Они были разработаны для облегчения
      просмотра каталога, так как пакаджей уже имеется достаточно много и еще
      больше их появляется, а пользователи отвернутся от нас, если список не
      понравится их взору!</para>

    <para>Имя пакаджа должно иметь вид
      <filename><replaceable><optional>language<optional>_region</optional></optional>-name<optional><optional>-</optional>compiled.specifics</optional>-version.numbers</replaceable></filename>.</para>

    <para>Имя пакаджа определяется как
      <literal>${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}</literal>.
      Вы должны задавать значения переменных в соответствии с этим
      форматом.</para>

    <orderedlist>
      <listitem>
	<para>FreeBSD пытается поддерживать языки, на которых разговаривают
	  ее пользователи.  Часть <replaceable>language-</replaceable>
	  должна быть двухсимвольным сокращением от названия языка по
	  стандарту ISO-639, если порт специфичен для конкретного языка.
	  Примерами являются <literal>ja</literal> для японского,
	  <literal>ru</literal> для русского, <literal>vi</literal> для
	  вьетнамского, <literal>zh</literal> для китайского,
	  <literal>ko</literal> для корейского и <literal>de</literal> для
	  немецкого языков.</para>

	<para>Если ваш порт специфичен для конкретного региона внутри области
	  использования языка, добавьте также двухсимвольный код страны.
	  Примерами являются <literal>en_US</literal> для US English и
	  <literal>fr_CH</literal> для Swiss French.</para>

        <para>Часть <replaceable>language-</replaceable> должна задаваться в
          переменной <makevar>PKGNAMEPREFIX</makevar>.</para>
      </listitem>

      <listitem>
	<para>Первая буква части <filename>name</filename> должна быть в нижнем
          регистре.  (Оставшаяся часть названия может содержать буквы в
          верхнем регистре, так что принимайте решение сами, когда преобразуете
          имя программного пакета, содержащего в имени некоторое количество
          заглавных букв.)  Существует традиция именовать модули для Perl 5,
          добавляя впереди <literal>p5-</literal> и преобразуя пару двоеточий в
          дефис; например, модуль <literal>Data::Dumper</literal> будет
          именоваться <literal>p5-Data-Dumper</literal>.  Если программное
          обеспечение содержит в имени числа, дефисы или подчеркивания, то вы
          можете включить также и их (например,
          <literal>kinput2</literal>).</para>
      </listitem>

      <listitem>
	<para>Если порт может быть построен с различными <link
	  linkend="porting-masterdir">статически заданными значениями по
	  умолчанию</link> (обычно это часть имени каталога в семействе
	  портов), то часть <replaceable>-compiled.specifics</replaceable>
	  должна определять вкомпилированные значения по умолчанию (дефис
	  не обязателен).  Примерами являются размеры бумаги и
	  шрифтов.</para>

        <para>Часть <replaceable>compiled.specifics</replaceable> должна
          задаваться в переменной <makevar>PKGNAMESUFFIX</makevar>.</para>
      </listitem>

      <listitem>
	<para>Строка с номером версии должна следовать за дефисом
	  (<literal>-</literal>) и являться списком разделенных двоеточием
	  чисел и букв в нижнем регистре.  В частности, не разрешается иметь
	  еще один дефис внутри строки с обозначением номера версии.
	  Единственным исключением является строчка <literal>pl</literal>
	  (означающая `уровень патчей'), которая может использоваться
	  <emphasis>только</emphasis> тогда, когда у программного обеспечения
	  нет старшего и младшего номера версии.  Если в номер версии
          программного обеспечения включена строчка типа "alpha", "beta", "rc"
          или "pre", возьмите из неё первую букву и поставьте её непосредственно
          после точки.  Если после таких строк номер версии ещё продолжается,
          то после буквы должно следовать число без дополнительной разделяющей
          точки.</para>

        <para>Смысл такого формата заключается в удобстве сортировки портов
          по номеру версии.  В частности, следите за тем, чтобы компоненты
          номера версии разделялись точкой, и если там присутствует дата,
          то используйте формат
          <literal><replaceable>yyyy</replaceable>.<replaceable>mm</replaceable>.<replaceable>dd</replaceable></literal>, но не
          <literal><replaceable>dd</replaceable>.<replaceable>mm</replaceable>.<replaceable>yyyy</replaceable></literal>
          или не совместимый с проблемой Г2000
          <literal><replaceable>yy</replaceable>.<replaceable>mm</replaceable>.<replaceable>dd</replaceable></literal>.</para>
      </listitem>
    </orderedlist>

    <para>Вот несколько (реальных) примеров того, как преобразовать имя из
      оригинального, придуманного авторами, к подходящему для имени
      пакаджа:</para>

    <informaltable frame="none">
    <tgroup cols="6">
    <thead>
      <row>
	<entry>Имя дистрибутива</entry>
        <entry><makevar>PKGNAMEPREFIX</makevar></entry>
        <entry><makevar>PORTNAME</makevar></entry>
        <entry><makevar>PKGNAMESUFFIX</makevar></entry>
        <entry><makevar>PORTVERSION</makevar></entry>
	<entry>Обоснование</entry>
      </row>
    </thead>

    <tbody>
      <row>
	<entry>mule-2.2.2</entry>
        <entry>(пусто)</entry>
        <entry>mule</entry>
        <entry>(пусто)</entry>
        <entry>2.2.2</entry>
	<entry>Изменений не потребовалось</entry>
      </row>

      <row>
        <entry>XFree86-3.3.6</entry>
        <entry>(пусто)</entry>
        <entry>XFree86</entry>
        <entry>(пусто)</entry>
        <entry>3.3.6</entry>
	<entry>Изменений не потребовалось</entry>
      </row>

      <row>
	<entry>EmiClock-1.0.2</entry>
        <entry>(пусто)</entry>
        <entry>emiclock</entry>
        <entry>(пусто)</entry>
        <entry>1.0.2</entry>
	<entry>Для отдельных программ имена с заглавными буквами
	  запрещены</entry>
      </row>

      <row>
	<entry>rdist-1.3alpha</entry>
        <entry>(пусто)</entry>
        <entry>rdist</entry>
        <entry>(пусто)</entry>
        <entry>1.3.a</entry>
	<entry>Строчки типа <literal>alpha</literal> запрещены</entry>
      </row>

      <row>
	<entry>es-0.9-beta1</entry>
        <entry>(пусто)</entry>
        <entry>es</entry>
        <entry>(пусто)</entry>
        <entry>0.9.b1</entry>
	<entry>Строчки типа <literal>beta</literal> запрещены</entry>
      </row>

      <row>
	<entry>mailman-2.0rc3</entry>
	<entry>(пусто)</entry>
	<entry>mailman</entry>
	<entry>(пусто)</entry>
	<entry>2.0.r3</entry>
	<entry>Строчки типа <literal>rc</literal> запрещены</entry>
      </row>

      <row>
	<entry>v3.3beta021.src</entry>
        <entry>(пусто)</entry>
        <entry>tiff</entry>
        <entry>(пусто)</entry>
        <entry>3.3</entry>
	<entry>Что это такое было вообще?</entry>
      </row>

      <row>
	<entry>tvtwm</entry>
        <entry>(пусто)</entry>
        <entry>tvtwm</entry>
        <entry>(пусто)</entry>
        <entry>pl11</entry>
	<entry>Всегда требуется указание номера версии</entry>
      </row>

      <row>
	<entry>piewm</entry>
        <entry>(пусто)</entry>
	<entry>piewm</entry>
        <entry>(пусто)</entry>
        <entry>1.0</entry>
	<entry>Всегда требуется указание номера версии</entry>
      </row>

      <row>
	<entry>xvgr-2.10pl1</entry>
        <entry>(пусто)</entry>
        <entry>xvgr</entry>
        <entry>(пусто)</entry>
        <entry>2.10.1</entry>
	<entry><literal>pl</literal> разрешено только при отсутствии
	  старшего/младшего номера версии</entry>
      </row>

      <row>
	<entry>gawk-2.15.6</entry>
        <entry>ja-</entry>
        <entry>gawk</entry>
        <entry>(пусто)</entry>
        <entry>2.15.6</entry>
	<entry>Версия на японском языке</entry>
      </row>

      <row>
	<entry>psutils-1.13</entry>
        <entry>(пусто)</entry>
        <entry>psutils</entry>
        <entry>-letter</entry>
        <entry>1.13</entry>
	<entry>Размер бумаги задается статически во время построения
	  пакаджа</entry>
      </row>

      <row>
	<entry>pkfonts</entry>
        <entry>(пусто)</entry>
	<entry>pkfonts</entry>
	<entry>300</entry>
        <entry>1.0</entry>
	<entry>Пакадж для шрифтов 300dpi</entry>
      </row>
    </tbody>
    </tgroup>
    </informaltable>

    <para>Если в исходном коде абсолютно нет информации о номере версии и не
      похоже, что автор собирается выпускать другую версию, то в качестве
      номера версии задайте просто <literal>1.0</literal> (как в примере с
      piewm выше).  В противном случае спросите автора программы или
      используйте дату
      (<literal><replaceable>yyyy</replaceable>.<replaceable>mm</replaceable>.<replaceable>dd</replaceable></literal>)
      в качестве номера версии.</para>
  </chapter>

  <chapter id="porting-categories">
    <title>Категории</title>

    <para>Как вы уже знаете, порты разделяются на несколько категорий.
      Но чтобы эта классификация работала хорошо, очень важно, чтобы как те,
      кто занимается портированием, так и пользователи понимали, что содержит
      каждая категория, и как мы определяем, что помещать в каждую
      из них.</para>

    <sect1>
      <title>Текущий список категорий</title>

      <para>Во-первых, это текущий список категорий.  Те, которые отмечены
	звездочкой (<literal>*</literal>), являются
	<emphasis>виртуальными</emphasis> категориями&mdash;они не имеют
	собственного подкаталога в дереве портов.</para>

      <note>
	<para>Для каждой виртуальной категории имеется файл
	  <filename>pkg/COMMENT</filename> с ее однострочным описанием
	  в соответствующем подкаталоге (например,
	  <filename>archivers/pkg/COMMENT</filename>).</para>
      </note>

      <informaltable frame="none">
      <tgroup cols="2">
      <thead>
	<row>
	  <entry>Категория</entry>
	  <entry>Описание</entry>
	</row>
      </thead>

      <tbody>
	<row>
	  <entry><filename>afterstep*</filename></entry>
	  <entry>Порты, поддерживающие менеджер окон AfterStep.</entry>
	</row>

	<row>
	  <entry><filename>archivers</filename></entry>
	  <entry>Инструменты для работы с архивами.</entry>
	</row>

	<row>
	  <entry><filename>astro</filename></entry>
	  <entry>Приложения, связанные с астрономией.</entry>
	</row>

	<row>
	  <entry><filename>audio</filename></entry>
	  <entry>Поддержка работы со звуком.</entry>
	</row>

	<row>
	  <entry><filename>benchmarks</filename></entry>
	  <entry>Утилиты для измерения производительности системы.</entry>
	</row>

	<row>
	  <entry><filename>biology</filename></entry>
	  <entry>Программное обеспечение, связанное с биологией.</entry>
	</row>

	<row>
	  <entry><filename>cad</filename></entry>
	  <entry>Инструменты Систем Автоматизированного
	    Проектирования.</entry>
	</row>

	<row>
	  <entry><filename>chinese</filename></entry>
	  <entry>Поддержка китайского языка.</entry>
	</row>

	<row>
	  <entry><filename>comms</filename></entry>
	  <entry>Коммуникационное программное обеспечение.  В основном
	    программы для работы с последовательным портом.</entry>
	</row>

	<row>
	  <entry><filename>converters</filename></entry>
	  <entry>Утилиты для преобразования символьных форматов.</entry>
	</row>

	<row>
	  <entry><filename>databases</filename></entry>
	  <entry>Базы данных.</entry>
	</row>

	<row>
	  <entry><filename>deskutils</filename></entry>
	  <entry>То, что было на столе до изобретения компьютеров.</entry>
	</row>

	<row>
	  <entry><filename>devel</filename></entry>
	  <entry>Утилиты для разработки программного обеспечения.  Не
	    помещайте сюда библиотеки просто потому что это
	    библиотеки&mdash;если они подпадают под какую-то другую
	    категорию, то их быть здесь не должно.</entry>
	</row>

	<row>
	  <entry><filename>editors</filename></entry>
	  <entry>Редакторы общего назначения.  Специализированные редакторы
	    относят к разделу для соответствующих инструментов (например,
	    редактор математических формул попадает в категорию
	    <filename>math</filename>).</entry>
	</row>

	<row>
	  <entry><filename>elisp*</filename></entry>
	  <entry>Порты для Emacs lisp.</entry>
	</row>

	<row>
	  <entry><filename>emulators</filename></entry>
	  <entry>Эмуляторы других операционных систем.	Эмуляторы терминалов
	    сюда <emphasis>не</emphasis> относятся&mdash;те, которые
	    разработаны для X, должны быть в категории
	    <filename>x11</filename>, а текстовые в
	    <filename>comms</filename> или <filename>misc</filename>, в
	    зависимости от конкретного их предназначения.</entry>
	</row>

	<row>
          <entry><filename>french</filename></entry>
          <entry>Поддержка французского языка.</entry>
        </row>

        <row>
	  <entry><filename>ftp</filename></entry>
	  <entry>Клиенты и серверы FTP.  Если ваш порт понимает как FTP,
	    так и HTTP, поместите его в категорию <filename>ftp</filename> и
	    укажите вторичную категорию <filename>www</filename>.</entry>
	</row>

	<row>
	  <entry><filename>games</filename></entry>
	  <entry>Игры.</entry>
	</row>

	<row>
	  <entry><filename>german</filename></entry>
	  <entry>Поддержка немецкого языка.</entry>
	</row>

	<row>
	  <entry><filename>gnome*</filename></entry>
	  <entry>Порты проекта GNU Object Model Environment (GNOME)
	    Project.</entry>
	</row>

	<row>
	  <entry><filename>graphics</filename></entry>
	  <entry>Графические утилиты.</entry>
        </row>

        <row>
          <entry><filename>hebrew</filename></entry>
          <entry>Поддержка иврита.</entry>
	</row>

	<row>
	  <entry><filename>irc</filename></entry>
	  <entry>Утилиты для работы с Internet Relay Chat.</entry>
	</row>

	<row>
	  <entry><filename>ipv6*</filename></entry>
	  <entry>Программное обеспечение, связанное с IPv6.</entry>
	</row>

	<row>
	  <entry><filename>japanese</filename></entry>
	  <entry>Поддержка японского языка.</entry>
	</row>

	<row>
	  <entry><filename>java</filename></entry>
	  <entry>Поддержка языка Java.</entry>
	</row>

	<row>
	  <entry><filename>kde*</filename></entry>
	  <entry>Порты проекта K Desktop Environment (KDE) Project.</entry>
	</row>

	<row>
	  <entry><filename>korean</filename></entry>
	  <entry>Поддержка корейского языка.</entry>
	</row>

	<row>
	  <entry><filename>lang</filename></entry>
	  <entry>Языки программирования.</entry>
	</row>

	<row>
	  <entry><filename>linux*</filename></entry>
	  <entry>Linux приложения и утилиты.</entry>
	</row>

	<row>
	  <entry><filename>mail</filename></entry>
	  <entry>Программы для работы с электронной почтой..</entry>
	</row>

	<row>
	  <entry><filename>math</filename></entry>
	  <entry>Программное обеспечение для численных вычислений и другие
	    утилиты, связанные с математикой.</entry>
	</row>

	<row>
	  <entry><filename>mbone</filename></entry>
	  <entry>Приложения для MBone.</entry>
	</row>

	<row>
	  <entry><filename>misc</filename></entry>
	  <entry>Различные утилиты&mdash;в основном то, что не попадает в
	    другие категории.  Это единственная категория, которая не должна
	    указываться вместе с любой другой невиртуальной категорией.  Если
	    вы указываете <literal>misc</literal> вместе с чем-то еще в
	    строке <makevar>CATEGORIES</makevar>, это значит, что вы можете
	    спокойно удалить <literal>misc</literal> и просто поместить порт
	    в этот другой подкаталог!</entry>
	</row>

	<row>
	  <entry><filename>net</filename></entry>
	  <entry>Различное сетевое программное обеспечение.</entry>
	</row>

	<row>
	  <entry><filename>news</filename></entry>
	  <entry>Программное обеспечение для работы с конференциями
	    USENET.</entry>
	</row>

	<row>
	  <entry><filename>offix*</filename></entry>
	  <entry>Порты из набора OffiX.</entry>
	</row>

	<row>
	  <entry><filename>palm</filename></entry>
	  <entry>Программная поддержка 3Com Palm(tm).</entry>
	</row>

	<row>
	  <entry><filename>perl5*</filename></entry>
	  <entry>Порты, которым для работы требуется perl версии 5.</entry>
        </row>

        <row>
          <entry><filename>picobsd</filename></entry>
          <entry>Порты для поддержки PicoBSD.</entry>
	</row>

	<row>
	  <entry><filename>plan9*</filename></entry>
	  <entry>Различные программы из plan9.</entry>
	</row>

	<row>
	  <entry><filename>print</filename></entry>
	  <entry>Программное обеспечение для печати.  Инструменты для верстки
	    (просмотрщики и тому подобное) тоже относятся сюда.</entry>
	</row>

	<row>
	  <entry><filename>python*</filename></entry>
	  <entry>Программное обеспечение, написанное на языке python.</entry>
        </row>

        <row>
          <entry><filename>ruby*</filename></entry>
	  <entry>Программное обеспечение, написанное на языке ruby.</entry>
	</row>

	<row>
	  <entry><filename>russian</filename></entry>
	  <entry>Поддержка русского языка.</entry>
	</row>

        <row>
          <entry><filename>science</filename></entry>
          <entry>Научные программы, которые не подпадают под другие категории,
            скажем, <filename>astro</filename>, <filename>biology</filename>
            или <filename>math</filename>.</entry>
        </row>

	<row>
	  <entry><filename>security</filename></entry>
	  <entry>Программы, обеспечивающие безопасность системы.</entry>
	</row>

	<row>
	  <entry><filename>shells</filename></entry>
	  <entry>Различные командные процессоры.</entry>
	</row>

	<row>
	  <entry><filename>sysutils</filename></entry>
	  <entry>Системные утилиты.</entry>
	</row>

	<row>
	  <entry><filename>tcl76*</filename></entry>
	  <entry>Порты, которым для работы нужен Tcl версии 7.6.</entry>
	</row>

	<row>
	  <entry><filename>tcl80*</filename></entry>
	  <entry>Порты, которым для работы нужен Tcl версии 8.0.</entry>
	</row>

	<row>
	  <entry><filename>tcl81*</filename></entry>
	  <entry>Порты, которым для работы нужен Tcl версии 8.1.</entry>
	</row>

	<row>
	  <entry><filename>tcl82*</filename></entry>
	  <entry>Порты, которым для работы нужен Tcl версии 8.2.</entry>
	</row>

	<row>
	  <entry><filename>textproc</filename></entry>
	  <entry>Утилиты для текстовой обработки.  Инструменты для верстки
	    помещаются в print/, а не сюда.</entry>
	</row>

	<row>
	  <entry><filename>tk42*</filename></entry>
	  <entry>Порты, которым для работы нужен Tk версии 4.2.</entry>
	</row>

	<row>
	  <entry><filename>tk80*</filename></entry>
	  <entry>Порты, которым для работы нужен Tk версии 8.0.</entry>
	</row>

	<row>
	  <entry><filename>tk81*</filename></entry>
	  <entry>Порты, которым для работы нужен Tk версии 8.1.</entry>
	</row>

	<row>
	  <entry><filename>tk82*</filename></entry>
	  <entry>Порты, которым для работы нужен Tk версии 8.2.</entry>
	</row>

	<row>
	  <entry><filename>tkstep80*</filename></entry>
	  <entry>Порты, которым для работы нужен TkSTEP версии 8.0.</entry>
        </row>

        <row>
          <entry><filename>ukrainian</filename></entry>
          <entry>Поддержка украинского языка.</entry>
	</row>

	<row>
	  <entry><filename>vietnamese</filename></entry>
	  <entry>Поддержка вьетнамского языка.</entry>
	</row>

	<row>
	  <entry><filename>windowmaker*</filename></entry>
	  <entry>Порты, поддерживающие менеджер окон WindowMaker</entry>
	</row>

	<row>
	  <entry><filename>www</filename></entry>
	  <entry>Программное обеспечение, связанное с World Wide Web.
	    Поддержка языка HTML относится сюда же.</entry>
	</row>

	<row>
	  <entry>x11</entry>
	  <entry>X Window System и иже с ними.	Эта категория предназначена
	    только для программного обеспечения, которое поддерживает
	    оконную систему.  Не помещайте сюда обычные приложения X.  Если
	    ваш порт является приложением для X, задайте
	    <makevar>USE_XLIB</makevar> (что подразумевается при
	    использовании <makevar>USE_IMAKE</makevar>) и укажите подходящую
	    категорию.	Кроме того, многие такие приложения относятся к
	    категориям <filename>x11-*</filename> (смотрите ниже).</entry>
	</row>

	<row>
	  <entry><filename>x11-clocks</filename></entry>
	  <entry>Часы для X11.</entry>
	</row>

	<row>
	  <entry><filename>x11-fm</filename></entry>
	  <entry>Менеджеры файлов для X11.</entry>
	</row>

	<row>
	  <entry><filename>x11-fonts</filename></entry>
	  <entry>Шрифты для X11 и утилиты для работы с ними.</entry>
	</row>

	<row>
	  <entry><filename>x11-servers</filename></entry>
	  <entry>Серверы для X11.</entry>
	</row>

	<row>
	  <entry><filename>x11-toolkits</filename></entry>
	  <entry>Пакеты разработчика для X11.</entry>
	</row>

	<row>
	  <entry><filename>x11-wm</filename></entry>
	  <entry>Оконные менеджеры для X11.</entry>
        </row>

        <row>
          <entry><filename>zope*</filename></entry>
          <entry>Поддержка zope.</entry>
	</row>
      </tbody>
      </tgroup>
      </informaltable>
    </sect1>

    <sect1>
      <title>Выбор правильной категории</title>

      <para>Так как многие категории перекрываются, вам часто необходимо
	будет выбирать, какая их них должна быть основной для вашего порта.
	Есть несколько правил, по которым можно решить этот вопрос. Вот
	список приоритетов, в уменьшающейся степени предпочтения.</para>

      <itemizedlist>
	<listitem>
	  <para>Сначала всегда идут категории, специфичные для языков.
	    Например, если ваш порт устанавливает японские шрифты для X11,
	    то строчка <makevar>CATEGORIES</makevar> должна иметь вид
	    <literal>japanese x11-fonts</literal>.</para>
	</listitem>

	<listitem>
	  <para>Более конкретные категории предпочтительней перед точных.  В
	    частности, редактор HTML должен быть описан как
	    <literal>www editors</literal>, а не наоборот.  Кроме того, вам не
	    нужно указывать категорию <literal>net</literal>, если порт
	    относится к любой из категорий <literal>irc</literal>,
	    <literal>mail</literal>, <literal>mbone</literal>,
	    <literal>news</literal>, <literal>security</literal> или
	    <literal>www</literal>.</para>
	</listitem>

	<listitem>
	  <para><literal>x11</literal> используется как вторичная категория
	    только в случае, когда в качестве основной категории указан
	    естественный язык.	В частности, вам не нужно указывать
	    <literal>x11</literal> в качестве категории для
	    приложений X.</para>
	</listitem>

	<listitem>
	  <para>Режимы для редактора <application>Emacs</application> должны
	    помещаться в ту же категорию, что и приложение, которое
	    поддерживается этим режимом, а не в <filename>editors</filename>.
	    Например, режим <application>Emacs</application> для
	    редактирования исходного кода некоторого языка программирования
	    должен быть помещен в категорию <filename>lang</filename>.</para>
	</listitem>

	<listitem>
	  <para>Если ваш порт решительным образом не подпадает ни под какую
	    категорию, поместите его в <literal>misc</literal>.</para>
	</listitem>
      </itemizedlist>

      <para>Если вы не уверены в правильности выбора категории, пожалуйста,
	отметьте это в вашей посылке по <command>send-pr</command>, чтобы мы
	могли обсудить это до того, как включить порт в Коллекцию.  Если вы
	являетесь коммиттером, пошлите замечание на адрес &a.ports;, чтобы мы
	могли обсудить это&mdash;зачастую новые порты помещаются не в ту
	категорию только для того, чтобы их оттуда сразу же удалили.</para>
    </sect1>
  </chapter>

  <chapter>
    <title>Изменения в этом документе и системе портов</title>

    <para>Если вы сопровождаете большое количество портов, то должны
      отслеживать &a.ports;.  Важные изменения в схеме работы портов будут
      объявляться здесь.  Вы всегда можете найти более подробную информацию о
      самых последних изменениях в <ulink
      url="http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/Mk/bsd.port.mk">
      журнале изменений CVS файла bsd.port.mk</ulink>.</para>
  </chapter>

  <chapter>
    <title>Вот, парни, и все!</title>

    <para>Итак, малыш, это был длинный рассказ, не так ли?  Спасибо за то,
      что вы шли с нами до самого конца.  Теперь, когда вы знаете, как
      создавать порты, воспользуйтесь этими знаниями и преобразуйте все, что
      есть на свете, в порты!  Это самый легкий способ принять участие в
      Проекте FreeBSD!
      <!-- smiley --><emphasis>:-)</emphasis></para>
  </chapter>

</book>

<!--
     Local Variables:
     mode: sgml
     sgml-indent-data: t
     sgml-omittag: nil
     sgml-always-quote-attributes: t
     End:
-->
