5.7. Зависимости

Многие порты зависят от других портов. Это очень удобная замечательная особенность большинства Unix-подобных операционных систем, включая FreeBSD. Множество портов могут использовать общую зависимость совместно, а не включать её в состав каждого порта или пакета, который в ней нуждается. Имеется семь переменных, которые вы можете использовать для обеспечения того, что всё требуемое находится на машине пользователя. Имеется также несколько предопределённых переменных, отражающих зависимости для общих случаев, плюс ещё несколько для управления поведением зависимостей.

5.7.1. LIB_DEPENDS

Эта переменная указывает, от каких совместно используемых библиотек зависит порт. Это список пар lib:dir[:target] где lib - это имя библиотеки, dir - это каталог, в котором можно ее найти в случае, если ее нет на машине, и target - это цель, которую нужно вызвать в этом каталоге. Например,

LIB_DEPENDS=   jpeg:${PORTSDIR}/graphics/jpeg

проверит наличие библиотеки jpeg с любым номером версии и перейдет в подкаталог graphics/jpeg вашего дерева портов для ее построения и установки, если библиотека отсутствует. Часть target может быть опущена, если она равна DEPENDS_TARGET (по умолчанию install).

Замечание: Часть lib является регулярным выражением, которое вызывается для вывода, полученного из ldconfig -r. Разрешаются такие значения, как intl.9 и intl.[5-7]. Первый шаблон, intl.9, совпадает только с intl версии 9, в то время как intl.[5-7] совпадает с любым из: intl.5, intl.6 и intl.7.

Зависимость проверяется дважды, один раз внутри цели extract, а затем из цели install. Кроме того, имя зависимости помещается в пакет, так что pkg_add(1) будет автоматически его устанавливать, если его нет на пользовательской системе.

5.7.2. RUN_DEPENDS

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

Например,

RUN_DEPENDS=   ${LOCALBASE}/news/bin/innd:${PORTSDIR}/news/inn \
	       xmlcatmgr:${PORTSDIR}/textproc/xmlcatmgr

проверит существование файла или каталога /usr/local/news/bin/innd, и если ничего не будет найдено, то построит и установит порт из подкаталога news/inn дерева портов. Также будет выполнена проверка, присутствует ли в пути поиска исполняемый файл с именем xmlcatmgr, и перейдет в подкаталог textproc/xmlcatmgr вашего дерева портов для его построения и установки, если он не будет найден.

Замечание: В приведенном примере innd является выполнимым файлом; если выполнимый файл находится в месте, которое отсутствует в списке путей файлов, то вы должны указать полный путь к файлу.

Замечание: Официальным значением переменной поиска PATH, используемым в кластере построения портов является

/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

Зависимость проверяется внутри цели install. Кроме того, имя зависимости помещается в пакет, так что программа pkg_add(1) будет автоматически его устанавливать, если он не будет найден в пользовательской системе. Часть target может быть опущена, если она совпадает с DEPENDS_TARGET.

Довольно распространенной является ситуация, когда RUN_DEPENDS буквально такая же как BUILD_DEPENDS, особенно если переносимое программное обеспечение написано на языке сценариев, или если оно требует такое же окружение для исполнения, как и используемое во время построения. В этом случае, очень заманчивым или довольно естественным является присвоение одного другому:

RUN_DEPENDS= ${BUILD_DEPENDS}

Тем не менее, подобные присвоения могут загрязнять зависимости времени исполнения содержимым, не заданным в BUILD_DEPENDS исходного порта. Такое случается из-за ленивого вычисления в make(1) присваиваемых переменных. Представьте Makefile с переменными USE_*, которые обрабатываются в ports/Mk/bsd.*.mk для пополнения первоначальных зависимостей построения. Например, USE_GMAKE=yes добавляет devel/gmake в BUILD_DEPENDS. Для предотвращения загрязнения RUN_DEPENDS подобными дополнительными зависимостями проявляйте осторожность с присвоением с раскрытием, т.е. с раскрытием значения перед его присвоением переменной:

RUN_DEPENDS:=  ${BUILD_DEPENDS}

5.7.3. BUILD_DEPENDS

В этой переменной перечисляются выполнимые или обычные файлы, которые требуются порту для его построения. Как и RUN_DEPENDS, это список пар path:dir[:target] Например,

BUILD_DEPENDS=  unzip:${PORTSDIR}/archivers/unzip

будет проверять наличие выполнимого фала с именем unzip и перейдет в подкаталог archivers/unzip вашего дерева портов для его построения и установки, если последний не будет найден.

Замечание: Под ``построением'' здесь понимается всё, от распаковки до компиляции. Зависимость проверяется из цели extract. Часть target может быть опущена, если она совпадает с DEPENDS_TARGET.

5.7.4. FETCH_DEPENDS

В этой переменной перечисляются выполняемые файлы или просто файлы, которые требуются порту для сгрузки. Как и предыдущие две переменные, это список пар path:dir[:target] Например,

FETCH_DEPENDS=  ncftp2:${PORTSDIR}/net/ncftp2

будет проверять наличие выполняемого файла с именем ncftp2 и перейдет в каталог net/ncftp2 вашего дерева портов для его построения и установки, если тот не будет найден.

Зависимость проверяется при выполнении цели fetch. Часть target может быть опущена, если она совпадает с DEPENDS_TARGET.

5.7.5. EXTRACT_DEPENDS

В этой переменной указываются программы или файлы, которые требуются для распаковки порта. Как и в предыдущих случаях, это список пар вида path:dir[:target]. Например,

EXTRACT_DEPENDS=        unzip:${PORTSDIR}/archivers/unzip

будет проверять наличие программы с именем unzip, и перейдёт в подкаталог archivers/unzip вашего дерева портов для её построения и установки, если такой программы не будет найдено.

Зависимость проверяется внутри цели extract. Часть target может быть опущена, если она совпадает с DEPENDS_TARGET.

Замечание: Используйте эту переменную, только если распаковка не работает (по умолчанию предполагается использование gzip) и это не исправляется при помощи USE_ZIP или USE_BZIP2, которые описаны в Разд. 5.7.7.

5.7.6. PATCH_DEPENDS

Эта переменная указывает на программы или файлы, которые нужны порту для применения патчей. Как и в предыдущих случаях, это список пар вида path:dir[:target]. Например,

PATCH_DEPENDS=  ${NONEXISTENT}:${PORTSDIR}/java/jfc:extract

будет переходить в подкаталог java/jfc вашего дерева портов для распаковки.

Зависимость проверяется внутри цели patch. Часть target может быть опущена, если она совпадает с DEPENDS_TARGET.

5.7.7. USE_*

Для определения общих зависимостей, совместно используемых многими портами, предназначено несколько переменных. Их использование является необязательным, но помогает упростить избыточность файлов Makefile порта. Каждый из них оформляется как USE_*. Эти переменные можно использовать только в Makefile порта и ports/Mk/bsd.*.mk. Они не предназначены для установки пользователями параметров — используйте для этих целей PORT_OPTIONS.

Замечание: Установка любых USE_* в /etc/make.conf всегда является ошибочным действием. В частности, установка

USE_GCC=        3.4

добавит зависимость от gcc34 к каждому порту, включая сам gcc34!

Таблица 5-2. Переменные USE_*

Переменная Смысл
USE_BZIP2 tar-архивы порта упакованы при помощи bzip2.
USE_ZIP tar-архивы порта упакованы при помощи zip.
USE_BISON Для построения порт использует bison.
USE_CDRTOOLS Порт требует cdrecord из sysutils/cdrtools или sysutils/cdrtools-cjk в зависимости от предпочтений пользователя.
USE_GCC Порт требует для сборки специальную версию gcc. Точная версия может быть указана в значении переменной, например 3.4. Минимально необходимую версию можно указать как 3.4+. gcc из основной системы используется в случае, если он удовлетворяет запрошенной версии, иначе производится компиляция подходящей версии gcc из портов с коррекций переменных CC и CXX.

Переменные, относящиеся к gmake и сценарию configure, описаны в Разд. 6.3, а autoconf, automake и libtool описаны в Разд. 6.4. Переменные, связанные с Perl, описаны в Разд. 6.6. Переменные X11 перечислены в Разд. 6.7. Разд. 6.8 работает с переменными GNOME и Разд. 6.10 с KDE. Разд. 6.11 описывает переменные Java, а Разд. 6.12 содержит информацию об Apache, PHP и модулях PEAR. Python обсуждается в Разд. 6.13, а Ruby в Разд. 6.16. Разд. 6.17 предоставляет переменные, используемые для приложений SDL, и, наконец, Разд. 6.20 содержит информацию о приложении Xfce.

5.7.8. Минимальная версия зависимости

Минимальная версия зависимости может быть указана в любой переменной *_DEPENDS, за исключением LIB_DEPENDS, с использованием следующего синтаксиса:

p5-Spiffy>=0.26:${PORTSDIR}/devel/p5-Spiffy

Первое поле содержит название зависимого пакета, которое обязано совпадать с записью в базе данные пакетов, знак сравнения и версию версию пакета. Зависимость удовлетворяется если на машине установлен p5-Spiffy-0.26 или новее.

5.7.9. Замечания касательно зависимостей

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

Когда вы набираете команду make clean, эта операция также выполняется и над зависимостями этого порта. Если вы не хотите, чтобы это случилось, определите переменную NOCLEANDEPENDS в вашем окружении. Это может быть особенно нужным, если порт имеет нечто, что занимает много времени на построение, в своём списке зависимостей, например, KDE, GNOME или Mozilla.

Чтобы безусловно зависеть от другого порта, укажите переменную ${NONEXISTENT} в качестве первого поля переменной BUILD_DEPENDS или RUN_DEPENDS. Пользуйтесь этим, только когда вам нужно иметь исходный код другого порта. Вы можете сэкономить время на компиляции, указав также и цель. Например,

BUILD_DEPENDS=   ${NONEXISTENT}:${PORTSDIR}/graphics/jpeg:extract

всегда будет переходить в каталог с портом jpeg и распаковывать его.

5.7.10. Зацикленные зависимости фатальны

Важно: Не помещайте зацикливающиеся зависимости в дерево портов!

Технология построения портов не защищена от зацикленных зависимостей. Если вы создадите такую, то у кого-нибудь и где-нибудь установка FreeBSD будет немедленно сломана, а у остальных сломается несколько позже. Это на самом деле очень трудно распознать; если вы сомневаетесь, то перед внесением изменений проверьте, что выполнили следующее: cd /usr/ports; make index. Этот процесс может быть достаточно медленным на старых машинах, хотя мы сможете спасти большое количество людей—включая себя—от грядущих бед.

5.7.11. Автоматические зависимости и проблемы, которые они вызывают

Зависимости должны быть указаны либо явно, либо с использованием фреймворка OPTIONS. Использование прочих методов, таких как автоматическое обнаружение зависимостей, усложняет индексирование, что вызывает проблемы в управлении портами и пакетами.

Пример 5-8. Некорректное объявление необязательной зависимости

.include <bsd.port.pre.mk>

.if exists(${LOCALBASE}/bin/foo)
LIB_DEPENDS=	bar:${PORTSDIR}/foo/bar
.endif

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

Пример 5-9. Корректное объявление необязательной зависимости

OPTIONS_DEFINE=	BAR
BAR_DESC=	Enable bar support

.include <bsd.port.options.mk>

.if ${PORTOPTIONS:MBAR}
LIB_DEPENDS=	bar:${PORTSDIR}/foo/bar
.endif

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

5.7.12. USE_ и WANT_

Переменные USE_ задаются мейнтейнером порта для определения программного обеспечения, от которого этот порт зависит. Порт, для которого нужен Firefox, укажет

USE_FIREFOX=	yes

Некоторые переменные USE_ могут принимать номера версий или другие параметры. Например, порт, который требует Apache 2.2, укажет

USE_APACHE=	22

В некоторых случаях для большего контроля над зависимостями используются переменные WANT_, которые позволяют указывать требования в более точной форме. Например, взгляните на порт mail/squirrelmail. Этому порту нужны несколько модулей PHP, которые перечислены в переменной USE_PHP:

USE_PHP=	session mhash gettext mbstring pcre openssl xml

Эти модули доступны в версиях CLI и web, поэтому версия web выбрана с переменной WANT_:

WANT_PHP_WEB=	yes

Имеющиеся переменные USE_ и WANT_ определены в файлах /usr/ports/Mk.

По вопросам связанным с системой портов для FreeBSD, пишите по адресу <ports@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите по адресу <doc@FreeBSD.org>.