5.4. Дистрибутивные файлы

Во второй части Makefile задаётся, какие файлы и откуда должны быть сгружены для того, чтобы построить порт.

5.4.1. DISTVERSION/DISTNAME

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

Названия некоторых дистрибутивов, которые не укладываются в ${PORTNAME}-${PORTVERSION}-схему, могут быть автоматически обработаны посредством установки переменной DISTVERSION. PORTVERSION и DISTNAME будут унаследованы автоматически, но конечно же могут быть переопределены. Следующая таблица демонстрирует некоторые примеры:

DISTVERSION PORTVERSION
0.7.1d 0.7.1.d
10Alpha3 10.a3
3Beta7-pre2 3.b7.p2
8:f_17 8f.17

Замечание: Значения переменных PKGNAMEPREFIX и PKGNAMESUFFIX не влияют на значение DISTNAME. Заметьте также, что если значение WRKSRC равно work/${PORTNAME}-${PORTVERSION}, и в случае, когда оригинальный архив называется по имени, отличном от ${PORTNAME}-${PORTVERSION}${EXTRACT_SUFX}, скорее всего, вы должны оставить DISTNAME как есть— лучше переопределить DISTFILES, чем задавать значения как DISTNAME, так и WRKSRC (и, возможно, ещё и EXTRACT_SUFX).

5.4.2. MASTER_SITES

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

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

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

Если оригинальный архив находится на одном из таких популярных серверов, как SourceForge, GNU или Perl CPAN, то указывайте эти сайты в простой форме при помощи MASTER_SITE_* (к примеру, MASTER_SITE_SOURCEFORGE, MASTER_SITE_GNU или MASTER_SITE_PERL_CPAN. Просто укажите в переменной MASTER_SITES одно из этих значений, а в переменной MASTER_SITE_SUBDIR задайте путь к архиву. Вот пример:

MASTER_SITES=         ${MASTER_SITE_GNU}
MASTER_SITE_SUBDIR=   make

Или можно использовать сокращенный формат:

MASTER_SITES=	GNU/make

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

Для популярных сайтов существует несколько магических макросов с заранее известной структурой каталогов. Используйте для них сокращения, и система попытается угадать для вас правильный подкаталог.

MASTER_SITES=   SF

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

MASTER_SITES=   SF/stardict/WyabdcRealPeopleTTS/${PORTVERSION}

Что также можно записать в таком виде:

MASTER_SITES=	SF
MASTER_SITE_SUBDIR=	stardict/WyabdcRealPeopleTTS/${PORTVERSION}

Таблица 5-1. Популярные магические макросы для MASTER_SITES

Macro Assumed subdirectory
BERLIOS /${PORTNAME:L}
CHEESESHOP /packages/source/source/${DISTNAME:C/(.).*/\1/}/${DISTNAME:C/(.*)-[0-9].*/\1/}
DEBIAN /debian/pool/main/${PORTNAME:C/^((lib)?.).*$/\1/}/${PORTNAME}
GCC /pub/gcc/releases/${DISTNAME}
GNOME /pub/GNOME/sources/${PORTNAME}/${PORTVERSION:C/^([0-9]+\.[0-9]+).*/\1/}
GNU /gnu/${PORTNAME}
MOZDEV /pub/mozdev/${PORTNAME:L}
PERL_CPAN /pub/CPAN/modules/by-module/${PORTNAME:C/-.*//}
PYTHON /ftp/python/${PYTHON_PORTVERSION:C/rc[0-9]//}
RUBYFORGE /${PORTNAME:L}
SAVANNAH /${PORTNAME:L}
SF /project/${PORTNAME:L}/${PORTNAME:L}/${PORTVERSION}

5.4.3. EXTRACT_SUFX

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

К примеру, если дистрибутивный файл носит имя foo.tgz, а не более привычное foo.tar.gz, вы должны написать:

DISTNAME=      foo
EXTRACT_SUFX=  .tgz

Переменные USE_BZIP2, USE_XZ и USE_ZIP при необходимости автоматически устанавливают значение EXTRACT_SUFX в .tar.bz2, .tar.xz или .zip. Если ни одна из этих переменных не задана, то значение EXTRACT_SUFX по умолчанию устанавливается в .tar.gz.

Замечание: Вам не нужно задавать значения EXTRACT_SUFX и DISTFILES одновременно.

5.4.4. DISTFILES

Иногда имена сгружаемых файлов не соответствуют имени порта. К примеру, файл может называться source.tar.gz или подобным образом. В других случаях исходный код приложения может располагаться в нескольких отличающихся архивах, и все они должны быть сгружены.

Если это ваш случай, то задайте в переменной DISTFILES список разделённых пробелами имён файлов, которые нужно сгрузить.

DISTFILES=     source1.tar.gz source2.tar.gz

Если переменная DISTFILES не задана явно, то её значением по умолчанию будет ${DISTNAME}${EXTRACT_SUFX}.

5.4.5. EXTRACT_ONLY

Если только некоторые из DISTFILES должны быть распакованы—к примеру, часть из них является исходным кодом, а другие представляют собой неупакованную документацию—перечислите имена файлов, которые должны быть распакованы, в EXTRACT_ONLY.

DISTFILES=     source.tar.gz manual.html
EXTRACT_ONLY=  source.tar.gz

Если ни один из DISTFILES не должен распаковываться, то установите пустое значение переменной EXTRACT_ONLY.

EXTRACT_ONLY=

5.4.6. PATCHFILES

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

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

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

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

Замечание: Архив будет распакован вне исходного кода, как обычно, и к тому же его не нужно явно распаковывать, если это обычный архив gzip или compress. Если вы сделаете последнее, приложите дополнительные усилия для того, чтобы не перезаписать что-либо, уже существующее в этом каталоге. Также не забудьте добавить команду для удаления скопированного патча в цели pre-clean.

5.4.7. Несколько дистрибутивных файлов или патчей с различных серверов и подкаталогов (MASTER_SITES:n)

(Этот раздел можно считать немного ``повышенной трудности''; те, кто впервые знакомятся с этим текстом, могут пропустить этот раздел).

В этом разделе находится информация о механизме сгрузки, известном как MASTER_SITES:n и MASTER_SITES_NN. Далее мы будем называть этот механизм MASTER_SITES:n.

Сначала немного общей информации. В OpenBSD имеется полезная возможность, используемая в переменных DISTFILES и PATCHFILES, которая позволяет закреплять после имен файлов и патчей идентификаторы типа :n. Здесь n может быть из диапазона [0-9] и обозначать закреплённую группу. К примеру:

DISTFILES=      alpha:0 beta:1

В OpenBSD дистрибутивный файл alpha будет связан с переменной MASTER_SITES0, но не с нашей общей переменной MASTER_SITES, а файл beta с переменной MASTER_SITES1.

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

Просто представьте себе 2 файла в DISTFILES и 20 сайтов в MASTER_SITES; сайты очень медленные, причём beta находится на всех сайтах из MASTER_SITES, а alpha может быть найден только на 20-м сайте. Будет неправильно проверять их все, если создатель знает об этом, не правда ли? Неподходящее начало для таких прекрасных выходных!

Теперь, когда вы получили общее представление, просто представьте ещё большее количество DISTFILES и MASTER_SITES. Конечно, наш ``магистр доступности дистрибутивов'' представляет масштабы нагрузки на сеть, которую это даёт.

В последующих разделах информация будет даваться вместе с реализацией этой идеи во FreeBSD. Мы несколько улучшили концепцию OpenBSD.

5.4.7.1. Упрощённая информация

В этом разделе рассказывается, как быстро подготовить точную сгрузку нескольких дистрибутивных файлов и патчей с разных сайтов и каталогов. Мы описываем здесь случай упрощённого использования MASTER_SITES:n. Для большинства сценариев этого будет достаточно. Однако, если вам нужна дополнительная информация, обратитесь к следующему разделу.

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

Чтобы это поддерживать, за каждой записью в DISTFILES может следовать символ двоеточия и ``имя метки''. За каждым сайтом, перечисленным в MASTER_SITES, тоже следует двоеточие и метка, которая указывает, какие файлы дистрибутива должны быть сгружены с этого сайта.

Например, рассмотрим приложение, исходный код которого разделён на две части, source1.tar.gz и source2.tar.gz, которые должны быть сгружены с двух различных источников. Файл Makefile порта будет содержать строчки типа Прим. 5-1.

Пример 5-1. Упрощённое использование MASTER_SITES:n с 1 файлом на каждом сайте

MASTER_SITES=   ftp://ftp.example1.com/:source1 \
                ftp://ftp.example2.com/:source2
DISTFILES=      source1.tar.gz:source1 \
                source2.tar.gz:source2

Несколько дистрибутивных файлов могут иметь одну и ту же метку. Продолжая предыдущий пример, положим, что имеется и третий дистрибутивный файл, source3.tar.gz, который должен быть сгружен с ftp.example2.com. Тогда файл Makefile будет написан как Прим. 5-2.

Пример 5-2. Упрощённое использование MASTER_SITES:n с более чем 1 файлом на каждом сервере

MASTER_SITES=   ftp://ftp.example1.com/:source1 \
                ftp://ftp.example2.com/:source2
DISTFILES=      source1.tar.gz:source1 \
                source2.tar.gz:source2 \
                source3.tar.gz:source2

5.4.7.2. Подробная информация

Прекрасно, но пример из предыдущего раздела не показал вам всё, что вам нужно? В этом разделе мы подробно опишем, как работает механизм MASTER_SITES:n точной сгрузки и как вы можете изменить ваши порты, чтобы это использовать.

  1. За элементами могут следовать символы :n, где n это [^:,]+, то есть n может теоретически быть любой алфавитно-цифровой строкой, но пока мы будем ограничивать их [a-zA-Z_][0-9a-zA-Z_]+.

    Более того, совпадение строк чувствительно к регистру; другими словами, n отличается от N.

    Однако следующие слова не могут использоваться для этих нужд, так как они имеют особое значение: default, all и ALL (они используются для своих нужд в ii). Кроме того, DEFAULT является специальным ключевым словом (посмотрите 3).

  2. Элементы, за которыми следуют :n, принадлежат группе n, :m относится к группе m и так далее.

  3. Элементы без таких суффиксов не относятся ни к какой группе, то есть они принадлежат к особой группе DEFAULT. Если вы укажете суффиксом любого элемента DEFAULT, вы просто выполните излишнюю работу, если только вы не хотите отнесения элемента как к группе DEFAULT, так и какой-то другой в одно и то же время (посмотрите на пункт 5).

    Следующие примеры равнозначны, но первый более предпочтителен:

    MASTER_SITES=   alpha
    
    MASTER_SITES=   alpha:DEFAULT
    
  4. Группы не являются эксклюзивными, элемент может принадлежать к нескольким отличающимся группам одновременно, а группа может либо иметь несколько различных элементов, либо не иметь их вовсе. Повторяющиеся элементы в одной и той же группе будут являться просто повторяющимися элементами.

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

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

    Все следующие примеры имеют один смысл, но последний является предпочтительным:

    MASTER_SITES=   alpha alpha:SOME_SITE
    
    MASTER_SITES=   alpha:DEFAULT alpha:SOME_SITE
    
    MASTER_SITES=   alpha:SOME_SITE,DEFAULT
    
    MASTER_SITES=   alpha:DEFAULT,SOME_SITE
    
  6. Все серверы внутри определённой группы сортируются в соответствии с MASTER_SORT_AWK. Все группы в MASTER_SITES и PATCH_SITES тоже сортируются.

  7. Семантика групп может использоваться в любой из следующих переменных MASTER_SITES, PATCH_SITES, MASTER_SITE_SUBDIR, PATCH_SITE_SUBDIR, DISTFILES и PATCHFILES в соответствии со следующим синтаксисом:

    1. Все элементы MASTER_SITES, PATCH_SITES, MASTER_SITE_SUBDIR и PATCH_SITE_SUBDIR должны заканчиваться символом прямого слэша /. Если какие-то элементы принадлежат каким-то группам, постфикс группы :n должен следовать сразу после завершающего символа /. Механизм MASTER_SITES:n опирается на наличие завершающего символа / во избежание совпадающих элементов, где :n является корректной частью элемента с вхождениями, где :n обозначает группу n. Для целей совместимости, так как завершающий символ / ранее не требовался в элементах MASTER_SITE_SUBDIR и PATCH_SITE_SUBDIR, если символ, сразу предшествующий постфиксу, не является символом /, то :n будет считаться корректной частью элемента, а не постфиксом группы, даже если за элементом следует :n. Посмотрите Прим. 5-3 и Прим. 5-4.

      Пример 5-3. Подробное использование MASTER_SITES:n в MASTER_SITE_SUBDIR

      MASTER_SITE_SUBDIR=     old:n new/:NEW
      
      • Каталоги внутри группы DEFAULT -> old:n

      • Каталоги внутри группы NEW -> new

      Пример 5-4. Подробное использование MASTER_SITES:n с запятыми, несколькими файлами, несколькими серверами и несколькими подкаталогами

      MASTER_SITES=   http://site1/%SUBDIR%/ http://site2/:DEFAULT \
                      http://site3/:group3 http://site4/:group4 \
                      http://site5/:group5 http://site6/:group6 \
                      http://site7/:DEFAULT,group6 \
                      http://site8/%SUBDIR%/:group6,group7 \
                      http://site9/:group8
      DISTFILES=      file1 file2:DEFAULT file3:group3 \
                      file4:group4,group5,group6 file5:grouping \
                      file6:group7
      MASTER_SITE_SUBDIR=     directory-trial:1 directory-n/:groupn \
                              directory-one/:group6,DEFAULT \
                              directory
      

      Предыдущий пример приводит к следующей точной сгрузке. Серверы перечислены в точном порядке их использования.

      • file1 будет сгружаться с

        • MASTER_SITE_OVERRIDE

        • http://site1/directory-trial:1/

        • http://site1/directory-one/

        • http://site1/directory/

        • http://site2/

        • http://site7/

        • MASTER_SITE_BACKUP

      • file2 будет сгружаться точно также, как file1, так как они оба относятся к одной и той же группе

        • MASTER_SITE_OVERRIDE

        • http://site1/directory-trial:1/

        • http://site1/directory-one/

        • http://site1/directory/

        • http://site2/

        • http://site7/

        • MASTER_SITE_BACKUP

      • file3 будет сгружен с

        • MASTER_SITE_OVERRIDE

        • http://site3/

        • MASTER_SITE_BACKUP

      • file4 будет сгружаться с

        • MASTER_SITE_OVERRIDE

        • http://site4/

        • http://site5/

        • http://site6/

        • http://site7/

        • http://site8/directory-one/

        • MASTER_SITE_BACKUP

      • file5 будет сгружен с

        • MASTER_SITE_OVERRIDE

        • MASTER_SITE_BACKUP

      • file6 будет сгружаться с

        • MASTER_SITE_OVERRIDE

        • http://site8/

        • MASTER_SITE_BACKUP

  8. Как мне сгруппировать одну из специальных переменных из bsd.sites.mk, например, MASTER_SITE_SOURCEFORGE?

    Посмотрите Прим. 5-5.

    Пример 5-5. Подробное использование MASTER_SITES:n с MASTER_SITE_SOURCEFORGE

    MASTER_SITES=   http://site1/ ${MASTER_SITE_SOURCEFORGE:S/$/:sourceforge,TEST/}
    DISTFILES=      something.tar.gz:sourceforge
    

    something.tar.gz будет сгружаться со всех сайтов из MASTER_SITE_SOURCEFORGE.

  9. Как мне использовать это с переменными PATCH*?

    Все примеры выполнялись с переменными MASTER*, и они работают точно также и для PATCH*, как это можно видеть в Прим. 5-6.

    Пример 5-6. Упрощённое использование MASTER_SITES:n с PATCH_SITES.

    PATCH_SITES=    http://site1/ http://site2/:test
    PATCHFILES=     patch1:test
    

5.4.7.3. Что изменится для портов? А что не изменится?

  1. Все имеющиеся порты остаются без изменений. Код для механизма MASTER_SITES:n активируется, если только есть элементы, которые заканчиваются на :n, как и элементы в соответствии с вышеописанным синтаксисом, особенно как это показано в пункте 7.

  2. Цели порт остаются теми же самыми: checksum, makesum, patch, configure, build и так далее. С обычными исключениями для do-fetch, fetch-list, master-sites и patch-sites.

    • do-fetch: использует новую группировку с постфиксами в DISTFILES и PATCHFILES с соответствующими элементами групп в MASTER_SITES и PATCH_SITES, которые используют группы из MASTER_SITE_SUBDIR и PATCH_SITE_SUBDIR. Посмотрите Прим. 5-4.

    • fetch-list: работает также, как старая цель fetch-list с тем исключением, что она группирует, как и do-fetch.

    • master-sites и patch-sites: (несовместимы со старыми версиями) только возвращают элементы группы DEFAULT; на самом деле они выполняют цели master-sites-default и patch-sites-default соответственно.

      Более того, использование целей master-sites-all или patch-sites-all предпочтительно для непосредственной проверки MASTER_SITES или PATCH_SITES. Также работа прямой проверки в последующих версиях не гарантируется. Посмотрите iii.ii для получения более дополнительной информации об этих новых целях.

  3. Новые цели построения портов

    1. Имеются цели master-sites-n и patch-sites-n, которые будут перечислять элементы соответствующей группы n из MASTER_SITES и PATCH_SITES соответственно. К примеру, master-sites-DEFAULT и patch-sites-DEFAULT обе будут возвращать элементы группы DEFAULT, master-sites-test и patch-sites-test группы test и так далее.

    2. Имеются новые цели master-sites-all и patch-sites-all, которые выполняют работу старых master-sites и patch-sites. Они возвращают элементы всех групп, как если бы они все принадлежали одной и той же группе с тем, что она перечисляет ровно столько MASTER_SITE_BACKUP и MASTER_SITE_OVERRIDE, как и группы, определённые в DISTFILES или PATCHFILES; соответственно для master-sites-all и patch-sites-all.

5.4.8. DIST_SUBDIR

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

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

Замечание: Это не коснётся тех сайтов MASTER_SITES, которые вы указали в вашем файле Makefile.

5.4.9. ALWAYS_KEEP_DISTFILES

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

Пример 5-7. Использование ALWAYS_KEEP_DISTFILES.

.if defined(PACKAGE_BUILDING)
DISTFILES+=             foo.tar.gz
ALWAYS_KEEP_DISTFILES=  yes
.endif

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

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