<!--
     The FreeBSD Russian Documentation Project

     $FreeBSD$
     $FreeBSDru: frdp/doc/ru_RU.KOI8-R/books/fdp-primer/doc-build/chapter.sgml,v 1.4 2004/03/22 01:47:32 phantom Exp $

     Original revision: 1.14
-->

<!-- Copyright (c) 1999 Neil Blakey-Milner, All rights reserved.

     Redistribution and use in source (SGML DocBook) and 'compiled' forms
     (SGML HTML, PDF, PostScript, RTF and so forth) with or without
     modification, are permitted provided that the following conditions
     are met:

      1. Redistributions of source code (SGML DocBook) must retain the above
	 copyright notice, this list of conditions and the following
	 disclaimer as the first lines of this file unmodified.

      2. Redistributions in compiled form (transformed to other DTDs,
	 converted to PDF, PostScript, RTF and other formats) must reproduce
	 the above copyright notice, this list of conditions and the
	 following disclaimer in the documentation and/or other materials
	 provided with the distribution.

     THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
     POSSIBILITY OF SUCH DAMAGE.
-->

<chapter id="doc-build">
  <title>Процесс построения документации</title>

  <para>Главная цель этой главы заключается в четком описании того,
    <emphasis>как организован процесс построения документации</emphasis>, а
    также <emphasis>как внести изменения в этот процесс</emphasis>.</para>

  <para>После чтения этой главы вы должны:</para>

  <itemizedlist>
    <listitem>
      <para>Знать, что нужно для построения документации FDP, кроме того, что
	описано в <link linkend="tools">главе об инструментах для работы с
	SGML</link>.</para>
    </listitem>

    <listitem>
      <para>Уметь читать и понимать <application>make</application>-инструкции,
	которые присутствуют в файлах <filename>Makefile</filename> каждого
	документа, а также иметь представление о включаемых операциях из
	<filename>doc.project.mk</filename>.</para>
    </listitem>

    <listitem>
      <para>Уметь настраивать процесс построения при помощи
       	<application>make</application>-переменных и целей
	<application>make</application>.</para>
    </listitem>
  </itemizedlist>

  <sect1 id="doc-build-toolset">
    <title>Набор инструментов для построения документации FreeBSD</title>

    <para>Вот ваши инструменты.  Используйте их любым доступным вам
      способом.</para>

    <itemizedlist>
      <listitem>
	<para>Основным инструментом построения, который вам понадобится,
	  является <application>make</application>, и конкретно
	  <application>Berkeley Make</application>.</para>
      </listitem>

      <listitem>
	<para>Построение пакаджа выполняется утилитой FreeBSD
	  <application>pkg_create</application>.  Если вы не используете
	  FreeBSD, вы либо обходитесь без пакаджей, либо компилируете исходные
	  тексты самостоятельно.</para>
      </listitem>

      <listitem>
	<para><application>gzip</application> нужен для создания
	  компрессированных версий документа.  Компрессия
	  <application>bzip2</application> и архивы
	  <application>zip</application> также поддерживаются.
	  <application>tar</application> поддерживается, но он требуется при
	  построении пакаджа.</para>
      </listitem>

      <listitem>
	<para><application>install</application> является методом, используемым
	  по умолчанию для установки документации.  Однако есть и
	  альтернативы.</para>
      </listitem>
    </itemizedlist>

    <note>
      <para>Сомнительно, что вы не сможете найти последние утилиты, они
	отмечены для полноты.</para>
    </note>
  </sect1>

  <sect1 id="doc-build-makefiles">
    <title>Понимание make-файлов в дереве документации</title>

    <para>В дереве Проекта Документирования FreeBSD имеется три основных типа
      файлов <filename>Makefile</filename>.</para>

    <itemizedlist>
      <listitem>
	<para><link linkend="sub-make"><filename>Makefile</filename> в
	  подкаталоге</link> просто передает команды во вложенные каталоги.</para>
      </listitem>

      <listitem>
	<para><link linkend="doc-make"><filename>Makefile</filename> для
	  документации</link> описывает документ или документы, которые должны быть
	  получены из этого каталога.</para>
      </listitem>

      <listitem>
	<para><link linkend="make-includes">Включаемые
	  <application>make</application>-файлы</link> являются тем клеем, что
	  выполняет построение документации, и обычно представлены в виде
	  файлов
	  <filename>doc.<replaceable>xxx</replaceable>.mk</filename>.</para>
      </listitem>
    </itemizedlist>

    <sect2 id="sub-make">
      <title>Make-файлы в подкаталоге</title>

      <para>Эти <filename>Makefile</filename> обычно имеют такой вид:</para>

      <programlisting>SUBDIR =articles
SUBDIR+=books

COMPAT_SYMLINK = en

DOC_PREFIX?= ${.CURDIR}/..
.include "${DOC_PREFIX}/share/mk/doc.project.mk"</programlisting>

      <para>Обзорно, первые четыре непустые строчки задают
	<application>make</application>-переменные, <makevar>SUBDIR</makevar>,
	<makevar>COMPAT_SYMLINK</makevar> и
	<makevar>DOC_PREFIX</makevar>.</para>

      <para>Первая декларация <makevar>SUBDIR</makevar>, как и
	<makevar>COMPAT_SYMLINK</makevar>, показывает, как присваивать значение
	переменной, переопределяя все ранее определенные значения.</para>

      <para>Вторая инструкция <makevar>SUBDIR</makevar> показывает, как
	значение добавляется к текущему значению переменной.  Значение
	переменной <makevar>SUBDIR</makevar> теперь соответствует
	<literal>articles books</literal>.</para>

      <para>Присвоение <makevar>DOC_PREFIX</makevar> показывает, как значение
	присваивается переменной, но только если оно еще не определено.  Это
	полезно, если <makevar>DOC_PREFIX</makevar> не соответствует тому, что
	полагает об этом <filename>Makefile</filename> - пользователь может
	переопределить это значение и дать правильное значение.</para>

      <para>Так что все это значит?  <makevar>SUBDIR</makevar> определяет,
	в какие вложенные подкаталоги должна быть передана работа по
	построению.</para>

      <para><makevar>COMPAT_SYMLINK</makevar> касается исключительно
	символических ссылок для достижения совместимости (достаточно
	удивительно) языков с их официальной кодировкой
	(<filename>doc/en</filename> должна указывать на
	<filename>en_US.ISO-8859-1</filename>).</para>

      <para><makevar>DOC_PREFIX</makevar> является маршрутом к корню дерева
	Проекта Документирования FreeBSD.  Его не всегда легко найти и легко
	переопределить для достижения гибкости.  <makevar>.CURDIR</makevar>
	является встроенной <application>make</application>-переменной,
	хранящей путь к текущему каталогу.</para>

      <para>В последней строке включается системный
	<application>make</application>-файл
	<filename>doc.project.mk</filename> Проекта Документирования FreeBSD,
	доступный всем проектам, который является связующим звеном,
	преобразующим эти переменные во встроенные инструкции.</para>
    </sect2>

    <sect2 id="doc-make">
      <title>Make-файлы для документации</title>

      <para>Эти <filename>make</filename>-файлы задают набор
	<application>make</application>-переменных, которые описывают, как
	построить документацию, расположенную в этом каталоге.</para>

      <para>Вот пример:</para>

      <programlisting>MAINTAINER=nik@FreeBSD.org

DOC?= book

FORMATS?= html-split html

INSTALL_COMPRESSED?= gz
INSTALL_ONLY_COMPRESSED?=

# SGML content
SRCS=  book.sgml

DOC_PREFIX?= ${.CURDIR}/../../..

.include "$(DOC_PREFIX)/share/mk/docproj.docbook.mk"</programlisting>

      <para>Переменная <makevar>MAINTAINER</makevar> очень важна.  Эта
	переменная дает возможность указать владельца документа в Проекте
	Документирования FreeBSD, когда вы становитесь ответственным за его
	поддержку.</para>

      <para><makevar>DOC</makevar> является именем (предполагается расширение
	<filename>.sgml</filename>) главного документа, создаваемого в этом
	каталоге.  В <makevar>SRCS</makevar> перечисляются все отдельные файлы,
	которые составляют документ.  Сюда также должны быть включены важные
	файлы, изменение которых должно приводить к перестроению.</para>

      <para><makevar>FORMATS</makevar> указывает используемые по умолчанию
	форматы, которые применяются при построении этого документа.
	<makevar>INSTALL_COMPRESSED</makevar> является списком методов
	компрессии, которые должны использоваться при построении документа.
	<makevar>INSTALL_ONLY_COMPRESS</makevar>, пустая по умолчанию, должна
	быть непустой, если требуется построить только скомпрессированные
	документы.</para>

      <note>
	<para>Назначение опциональных переменных обсуждается в
	  <link linkend="sub-make">предыдущем разделе</link>.</para>
      </note>

      <para>Переменная <makevar>DOC_PREFIX</makevar> у включающие директивы
	должны быть вам уже известны.</para>
    </sect2>
  </sect1>

  <sect1 id="make-includes">
    <title>Включаемые make-файлы Проекта Документирования FreeBSD</title>

    <para>Лучше всего это описывается при обсуждении кода.  Вот системные
      включаемые файлы:</para>

    <itemizedlist>
      <listitem>
	<para><filename>doc.project.mk</filename> является главным включаемым
	  файлом проекта, который включает все остальные включаемые файлы, по
	  мере необходимости.</para>
      </listitem>

      <listitem>
	<para><filename>doc.subdir.mk</filename> обрабатывает прохождение по
	  дереву документов в процессе построения и установки.</para>
      </listitem>

      <listitem>
	<para><filename>doc.install.mk</filename> содержит переменные, которые
	  отражаются на правах доступа и установке документов.</para>
      </listitem>

      <listitem>
	<para><filename>doc.docbook.mk</filename> включается, если значением
	  переменной <makevar>DOCFORMAT</makevar> является
	  <literal>docbook</literal> и установлена переменная
	  <makevar>DOC</makevar>.</para>
      </listitem>
    </itemizedlist>

    <sect2>
      <title>doc.project.mk</title>

      <para>Рассмотрим пример:</para>

      <programlisting>DOCFORMAT?=	docbook
MAINTAINER?=	doc@FreeBSD.org

PREFIX?=	/usr/local
PRI_LANG?=	en_US.ISO8859-1

.if defined(DOC)
.if ${DOCFORMAT} == "docbook"
.include "doc.docbook.mk"
.endif
.endif

.include "doc.subdir.mk"
.include "doc.install.mk"</programlisting>

      <sect3>
	<title>Переменные</title>

	<para>Переменным <makevar>DOCFORMAT</makevar> и
	  <makevar>MAINTAINER</makevar> заданы значения по умолчанию, если они
	  не установлены в make-файле документа.</para>

	<para><makevar>PREFIX</makevar> является каталогом, под которым
	  установлены <link linkend="tools">инструменты для построения
	  документации</link>.  При обычной установке портов и пакаджей это
	  <filename>/usr/local</filename>.</para>

	<para><makevar>PRI_LANG</makevar> должна быть установлена в значение,
	  соответствующее языку и кодировке, являющейся естественной для тех
	  пользователей, кому предназначена документация.  По умолчанию это
	  US English.</para>

	<note>
	  <para><makevar>PRI_LANG</makevar> не влияет на то, какие документы
	    могут или будут строиться.  Ее основное назначение - создание
	    ссылок на часто упоминаемые документы в корне установки
	    документации FreeBSD.</para>
	</note>
      </sect3>

      <sect3>
	<title>Условия</title>

	<para>Строка <literal>.if defined(DOC)</literal> является примером
	  <application>make</application>-условия, которое, как и в других
	  программах, определяет дальнейшие действия, если какое-то условие
	  выполняется или нет.  <literal>defined</literal> является функцией,
	  которая возвращает информацию о том, определена данная переменная или
	  нет.</para>

	<para>Затем <literal>.if ${DOCFORMAT} == "docbook"</literal> проверяет,
	  является ли значением переменной <makevar>DOCFORMAT</makevar>
	  <literal>"docbook"</literal>, и в этом случае включается файл
	  <filename>doc.docbook.mk</filename>.</para>

	<para>Две строки <literal>.endif</literal> закрывают два вышестоящих
	  условия, отмечая конец их действия.</para>
      </sect3>
    </sect2>

    <sect2>
      <title>doc.subdir.mk</title>

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

      <sect3>
	<title>Переменные</title>

	<itemizedlist>
	  <listitem>
	    <para><makevar>SUBDIR</makevar> представляет из себя список
	      подкаталогов, которые должны быть охвачены процессом
	      построения.</para>
	  </listitem>

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

	  <listitem>
	    <para><makevar>COMPAT_SYMLINK</makevar> описано в разделе о
	      <link linkend="sub-make">make-файле подкаталога</link>.</para>
	  </listitem>
	</itemizedlist>
      </sect3>

      <sect3>
	<title>Цели и макросы</title>

	<para>Зависимости описываются парами
	  <literal><replaceable>target</replaceable>:
	  <replaceable>dependency1 dependency2 ...</replaceable></literal>, и
	  когда вам нужно построить <literal>target</literal>, вам необходимо
	  сначала построить список зависимостей.</para>

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

	<para>Особая зависимость <literal>.USE</literal> задает эквивалент
	  макроса.</para>

<programlisting>_SUBDIRUSE: .USE
.for entry in ${SUBDIR}
	@${ECHO} "===> ${DIRPRFX}${entry}"
	@(cd ${.CURDIR}/${entry} && \
	${MAKE} ${.TARGET:S/realpackage/package/:S/realinstall/install/} DIRPRFX=${DIRPRFX}${entry}/ )
.endfor</programlisting>

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

	<para>Что отличает этот макрос от других целей?  В основном то, что
	  он выполняется <emphasis>после</emphasis> инструкций, данных в
	  процедуре построения, в качестве зависимости для которой он
	  перечислен, и это не влияет на <makevar>.TARGET</makevar>, которая
	  является переменной, содержащей название текущей выполняемой
	  цели.</para>

<programlisting>clean: _SUBDIRUSE
	rm -f ${CLEANFILES}</programlisting>

	<para>В вышеприведенном фрагменте <maketarget>clean</maketarget> будет
	  использовать макрос <maketarget>_SUBDIRUSE</maketarget> после того,
	  как выполнит инструкцию <command>rm -f ${CLEANFILES}</command>.  В
	  результате это приведет к тому, что <maketarget>clean</maketarget>
	  будет углубляться по дереву каталогов, удаляя файлы после перехода
	  <emphasis>ниже</emphasis>, а не на пути назад.</para>

	<sect4>
	  <title>Предопределенные цели</title>

	  <itemizedlist>
	    <listitem>
	      <para>Цели <maketarget>install</maketarget> и
		<maketarget>package</maketarget> обе переходят вниз по дереву
	        каталогов, вызывая собственные выполняющие реальную работу
	        версии в подкаталогах.  (<maketarget>realinstall</maketarget>
	        и <maketarget>realpackage</maketarget> соответственно)</para>
	    </listitem>

	    <listitem>
	      <para><maketarget>clean</maketarget> удаляет файлы, созданные в
	        процессе построения (и тоже переходит вниз по дереву
	        каталогов).  <maketarget>cleandir</maketarget> делает то же
	        самое и также удаляет каталог, если он есть.</para>
	    </listitem>
	  </itemizedlist>
	</sect4>
      </sect3>

      <sect3>
	<title>Подробности об условиях</title>

	<itemizedlist>
	  <listitem>
	    <para><literal>exists</literal> является еще одной функцией
	      условия, которая возвращает истину, если указанный файл
	      существует.</para>
	  </listitem>

	  <listitem>
	    <para><literal>empty</literal> возвращает истину, если данная
	      переменная имеет пустое значение.</para>
	  </listitem>

	  <listitem>
	    <para><literal>target</literal> возвращает истину, если указанная
	      цель еще не существует.</para>
	  </listitem>
	</itemizedlist>
      </sect3>

      <sect3>
	<title>Циклы в make (.for)</title>

	<para><literal>.for</literal> дает способ повторить набор инструкций
	  для каждого элемента списка, заданного в переменной через пробел.  Он
	  делает это, присваивая переменной значение текущего элемента
	  перебираемого списка.</para>

<programlisting>_SUBDIRUSE: .USE
.for entry in ${SUBDIR}
	@${ECHO} "===> ${DIRPRFX}${entry}"
	@(cd ${.CURDIR}/${entry} && \
	${MAKE} ${.TARGET:S/realpackage/package/:S/realinstall/install/} DIRPRFX=${DIRPRFX}${entry}/ )
.endfor</programlisting>

	<para>В примере выше если переменная <makevar>SUBDIR</makevar> пуста,
	  то не предпринимается никаких действий; если она состоит из одного
	  или более элементов, то инструкции между <literal>.for</literal> и
	  <literal>.endfor</literal> будут повторены для каждого элемента,
	  причем <makevar>entry</makevar> будет заменена значением текущего
	  элемента.</para>
      </sect3>
    </sect2>
  </sect1>
</chapter>

<!--
     Local Variables:
     mode: sgml
     sgml-declaration: "../chapter.decl"
     sgml-indent-data: t
     sgml-omittag: nil
     sgml-always-quote-attributes: t
     sgml-parent-document: ("../book.sgml" "part" "chapter")
     End:
-->

