---
title: Глава 5. Рекомендации и требования к исходному коду
authors:
  - author: Poul-Henning Kamp
  - author: Giorgos Keramidas
---

[[policies]]
= Рекомендации и требования к исходному коду
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 5
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/developers-handbook/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

В этой главе описываются различные рекомендации и требования, которые должны соблюдаться в дереве исходных текстов FreeBSD.

[[policies-maintainer]]
== в make-файлах

Если некоторая часть дистрибутива FreeBSD поддерживается некоторым человеком или группой людей, они могут сообщить об этом миру, добавив строчку 

[.programlisting]
....
MAINTAINER= email-addresses
....

в файл [.filename]#Makefile#, соответствующий этой части исходного кода.

Смысл этого в следующем:

Сопровождающий владеет кодом и отвечает за него. Это означает, что он несет ответственность за исправление ошибок и закрывает сообщения о проблемах, имеющих отношение к этой части кода, а в случае программного обеспечения, взятого из третьих источников, соответственно отвечает за отслеживание новых версий.

Изменения в каталогах, для которых известен сопровождающий, прежде чем они будут внесены, должны быть посланы ему на рассмотрение. Только если сопровождающий не отвечает в течение достаточно большого периода времени на несколько посланий по электронной почте, разрешается внести изменения без участия сопровождающего. Однако рекомендуется, чтобы вы попытались передать изменения на рассмотрение кому-либо еще, если это вообще возможно.

Конечно же, нельзя назначать человека или группу лиц сопровождающими, если они не согласны выполнять эту работу. С другой стороны, необязательно это должен быть конкретный коммиттер, это может быть и группа людей.

[[policies-contributed]]
== Программное обеспечение сторонних производителей

Некоторые части дистрибутива FreeBSD состоят из программного обеспечения, которое сопровождается вне проекта FreeBSD. По историческим причинам мы называем такое программное обеспечение _контрибуцированным_ (contributed), или третьих сторон. Примерами этого могут служить утилиты sendmail, gcc и patch.

За последние несколько лет для работы с таким программным обеспечением использовались различные методы, и все они имели свои достоинства и недостатки. Абсолютно подходящего метода так и не нашлось.

По этой причине после некоторых дебатов был выбран и признан "официальным" один из этих методов, который необходимо применять в будущем при импортировании такого рода программного обеспечения. Более того, настоятельно рекомендуется с течением времени перевести существующее программное обеспечение третьих сторон на этот метод, так как он имеет значительные преимущества перед старым методом, включая возможность легкого получения diff-файлов относительно "официальных" версий исходных текстов кем угодно (даже не имеющим доступа к cvs). Это делает данный метод гораздо проще в использовании при необходимости выдачи изменений изначальным разработчикам такого программного обеспечения.

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

[NOTE]
====
Из-за досадных ограничений в дизайне формата файлов RCS и использовании веток поставщика в CVS, мелкие, тривиальные и/или косметические изменения _сильно не рекомендуется_ в файлах, которые все еще отслеживаются в ветке поставщика. Это касается и "исправления орфографических ошибок" как относящихся к категории "косметических" и избегаемых для файлов с версиями 1.1.x.x. Рост объема хранилища, вызванный изменением в один символ, может оказаться весьма большим.
====

В качестве примера того, как работает эта модель, будем использовать встраиваемый язык программирования TCL:

Каталог [.filename]#src/contrib/tcl# содержит исходные тексты пакета в том виде, в котором они распространяются его создателями. Части, которые полностью не применимы во FreeBSD, могут быть удалены. В случае Tcl подкаталоги [.filename]#mac#, [.filename]#win# и [.filename]#compat# были удалены перед операцией импортирования

Каталог [.filename]#src/lib/libtcl# содержит только файл [.filename]#Makefile# в стиле bmake, который использует стандартные правила [.filename]#bsd.lib.mk# make-файла для построения библиотеки и установки документации.

В каталоге [.filename]#src/usr.bin/tclsh# размещаются make-файлы в стиле bmake, которые отвечают за построение и установку программы `tclsh` и связанных с ней справочных страниц при помощи стандартных правил из [.filename]#bsd.prog.mk#.

Каталог [.filename]#src/tools/tools/tcl_bmake# содержит несколько shell-скриптов, которые могут помочь при обновлении программного обеспечения tcl. Они не являются частью строящегося и инсталлируемого программного обеспечения.

Здесь важно то, что каталог [.filename]#src/contrib/tcl# создавался в соответствии с правилами: Предполагается, что он содержит исходные тексты в том виде, в котором они распространяются (в соответствующей ветви поставщика CVS и без расширения ключевых слов RCS) с максимально малым количеством изменений, специфичных для FreeBSD. Утилита 'easy-import' на машине  поможет в импортировании, но если есть сомнения по поводу выполнения этой операции, то обязательно спросите совета и не действуйте слепо в расчете на то, что "все сработает". CVS не прощает ошибок импортирования и для ликвидации последствий больших ошибок требуются значительные усилия.

Из-за ранее отмеченных ограничений дизайна веток поставщиков в CVS требуется, чтобы "официальные" патчи от разработчика были сначала применены к распространяемым исходным текстам, а затем результат снова импортирован в ветку поставщика. Официальные патчи никогда не должны применяться к версии, извлеченной из хранилища FreeBSD, а затем "коммититься", так как это приведет к рассинхронизации дерева производителя и усложнит импортирование будущих версий, так как возникнут конфликты.

Так как многие пакеты содержат файлы, имеющие значение при обеспечении совместимости с другими, отличными от FreeBSD архитектурами и окружениями, то разрешается удалять части дистрибутивного дерева, не представляющие интереса для FreeBSD в целях уменьшения занимаемого дискового пространства. Файлы, содержащие замечания о юридических правах и информацию о релизе, касающуюся остальных файлов, удаляться _не_ должны.

Если это видится легким, то файлы [.filename]#Makefile# в стиле `bmake` могут быть сгенерированы из дистрибутивного дерева автоматически некоторой утилитой, чем-то, что позволит еще проще обновляться до новой версии. Если это будет сделано, то обязательно поместите эту утилиту (если необходимо) в каталог [.filename]#src/tools# вместе с самим портом, чтобы она была доступна будущим сопровождающим лицам.

В каталог [.filename]#src/contrib/tcl# должен быть добавлен файл [.filename]#FREEBSD-upgrade#, в котором нужно перечислить такие вещи:

* Какие файлы были оставлены
* Где был взят оригинальный дистрибутив и/или на каком основном официальном сайте он находится.
* Куда посылать патчи для разработчиков пакета
* Возможно, обзор сделанных изменений, специфичных для FreeBSD.

Однако, пожалуйста, не импортируйте [.filename]#FREEBSD-upgrade# вместе с исходными текстами этого программного обеспечения. Вместо этого вы должны выполнить команды `cvs add FREEBSD-upgrade ; cvs ci` после первоначального импортирования. Ниже дается пример описания из каталога [.filename]#src/contrib/cpio#:

[.programlisting]
....
This directory contains virgin sources of the original distribution files
on a "vendor" branch.  Do not, under any circumstances, attempt to upgrade
the files in this directory via patches and a cvs commit.  New versions or
official-patch versions must be imported.  Please remember to import with
"-ko" to prevent CVS from corrupting any vendor RCS Ids.

For the import of GNU cpio 2.4.2, the following files were removed:

	INSTALL 	cpio.info	mkdir.c
	Makefile.in	cpio.texi	mkinstalldirs

To upgrade to a newer version of cpio, when it is available:
	1. Unpack the new version into an empty directory.
	   [Do not make ANY changes to the files.]

	2. Remove the files listed above and any others that don't apply to
	   FreeBSD.

	3. Use the command:
		cvs import -ko -m 'Virgin import of GNU cpio v<version>' \
			src/contrib/cpio GNU cpio_<version>

	   For example, to do the import of version 2.4.2, I typed:
		cvs import -ko -m 'Virgin import of GNU v2.4.2' \
			src/contrib/cpio GNU cpio_2_4_2

	4. Follow the instructions printed out in step 3 to resolve any
	   conflicts between local FreeBSD changes and the newer version.

Do not, under any circumstances, deviate from this procedure.

To make local changes to cpio, simply patch and commit to the main
branch (aka HEAD).  Never make local changes on the GNU branch.

All local changes should be submitted to "cpio@gnu.ai.mit.edu" for
inclusion in the next vendor release.

obrien@FreeBSD.org - 30 March 1997
....

[[policies-encumbered]]
== Нежелательные файлы

Иногда может быть необходимо включить некоторый нежелательный для нас файл в дерево исходных текстов FreeBSD. Например, если устройство требует загрузки в него некоторого маленького двоичного кода перед тем, как устройство заработает, и мы не имеем исходных текстов этого кода, то говорится, что двоичный файл является нежелательным. Для включения нежелательных файлов в дерево исходных текстов FreeBSD имеются следующие соглашения.

. Любой файл, интерпретируемый или выполняемый системным(и) CPU, не в форме исходного кода, является нежелательным.
. Любой файл с лицензией, ограничивающей более, чем BSD или GNU, является нежелательным.
. Файл, содержащий загружаемые двоичные данные, используемые аппаратным обеспечением, не являются нежелательными, если только к нему не применимы условия (1) или (2). Он должен быть сохранен в нейтральном к архитектуре формате ASCII (рекомендуется применить утилиты file2c или uuencode).
. Любой нежелательный файл требует особого одобрения со стороны extref:{contributors}[Правления, staff-core] до того, как он будет добавлен в хранилище CVS.
. Нежелательные файлы помещаются в каталог [.filename]#src/contrib# или [.filename]#src/sys/contrib#.
. Части одного модуля должны храниться вместе. Нет необходимости разбивать их, если только нет совместного использования с кодом, не являющимся нежелательным.
. Объектные файлы именуются [.filename]#arch/filename.o.uu>#.
. Файлы ядра;
.. Должны всегда упоминаться в [.filename]#conf/files.*# (для упрощения построения).
.. Должны всегда присутствовать в [.filename]#LINT#, но extref:{contributors}[Правление, staff-core] решает в каждом конкретном случае, должны ли они быть раскомментированы или нет. Конечно, позже extref:{contributors}[Правление, staff-core] может изменить свое решение.
.. Вопрос о вхождении в состав релиза решается _Группой Выпусков Релизов_.

. Файлы уровня пользователя:
.. extref:{contributors}[Правление, staff-core] решает, должен ли код стать частью выполнения команды `make world`.
.. extref:{contributors}[Релиз инженер, staff-who] решает, войдут ли они в релиз.

[[policies-shlib]]
== Динамические библиотеки

Если вы добавляете поддержку динамических библиотек к порту или другой части программного обеспечения, которая этой возможностью не обладает, то номера версий должны назначаться по нижеследующим правилам. Как правило, получающиеся номера не имеют ничего общего с номером релиза программного обеспечения.

При построении динамической библиотеки используются три принципа:

* Начинаем с `1.0`
* Если есть изменение, которое имеет обратную совместимость, увеличиваем младший номер версии (заметьте, что системы ELF его игнорируют)
* Если есть изменение, не соблюдающее совместимость, увеличиваем старший номер версии

К примеру, добавление функций и исправление ошибок приводит к увеличению младшего номера версии, а удаление функций, изменение синтаксиса вызова функции и тому подобные изменения приводят к изменению старшего номера версии.

Следуйте схеме нумерации версий в форме старший.младший (_x_._y_). Наш динамический загрузчик формата a.out не умеет нормально работать с номерами версий в форме _x_._y_._z_. Любой номер версии после _y_ (то есть третье число) полностью игнорируется при сравнении номеров версий динамических библиотек для определения того, с какой библиотекой осуществлять компоновку. Если есть две динамические библиотеки, отличающиеся только "микро"-номером версии, то `ld.so` будет осуществлять компоновку с наибольшим номером. Другими словами: если вы компонуете с [.filename]#libfoo.so.3.3.3#, то компоновщик запишет в заголовках только `3.3` и будет выполнять компоновку с любой библиотекой, начинающейся с _libfoo.so.3.(все, что >= 3).(наибольшее из доступного)_.

[NOTE]
====
`ld.so` всегда будет использовать наибольшую "младшую" версию. Иными словами: он будет предпочитать использовать [.filename]#libc.so.2.2#, а не [.filename]#libc.so.2.0#, даже если программа изначально была скомпонована с [.filename]#libc.so.2.0#.
====

Вдобавок наш динамический компоновщик ELF совсем не работает с младшими версиями. Однако все же нужно указывать старший и младший номер версии, а наши файлы [.filename]#Makefile#"сделают все как нужно" в зависимости от типа системы.

Для библиотек не в составе портов, имеется наше соглашение на изменение номера версии динамической библиотеки только один раз между релизами. Кроме того, есть договоренность на изменение старшего номера динамической библиотеки только один раз между главными релизами ОС (например c 3.0 к 4.0). Когда вы делаете изменение в системной библиотеке, которое требует увеличения номера версии, посмотрите журналы коммитов изменений в файле [.filename]#Makefile#. Коммиттер отвечает за то, что первое такое изменение с момента релиза приведет к обновлению номера версии динамической библиотеки в файле [.filename]#Makefile#, а при других последующих изменениях этого бы не делалось.
