4.4. Создание патчей

Файлы, которые добавлялись или изменялись в процессе создания порта, могут быть выявлены программой diff(1), а результат работы этой программы может быть в дальнейшем передан программе patch(1). Такое действие с обычным файлом подразумевает сохранение копии файла с первоначальным содержимым перед внесением каких-либо изменений.

% cp file file.orig

Патчи сохраняются в виде файлов с именем patch-*, где * обозначает путь к файлу, к которому применяется патч, такой как patch-Imakefile или patch-src-config.h.

После того как файл был изменён, используется diff(1) для получения разницы между первоначальной и изменённой версиями. Параметр -u указывает diff(1) выводить разницу в <<унифицированном>> формате, который также является предпочтительным.

% diff -u file.orig file > patch-pathname-file

Для порождении патчей для новых добавляемых файлов используется параметр -N, который заставляет diff(1) трактовать несуществующие прежде файлы как если бы они существовали, но имели пустое содержимое:

% diff -u -N newfile.orig newfile > patch-pathname-newfile

Файлы с патчами помещаются в каталоге PATCHDIR (как правило, это files/), откуда они будут взяты автоматически. Все патчи обязаны быть сделаны относительно каталога WRKSRC (как правило, это каталог, в который распаковывается исходный архив и где будет выполняться построение). Для упрощения внесения изменений и обновлений избегайте наличия более чем одного патча для одного и того же файла (например, патчей patch-file и patch-file2, оба меняющих файл WRKSRC/foobar.c). Обратите внимание, что если путь к изменяемому файлу содержит символ подчеркивания (_), то патч должен содержать в своем имени два подчеркивания вместо одного. Например, для применения патча на файл с именем src/freeglut_joystick.c соответствующий патч следует назвать patch-src-freeglut__joystick.c.

Пожалуйста, используйте для именования патчей только символы [-+._a-zA-Z0-9]. Не используйте любые другие символы, кроме этих. Не называйте патчи как patch-aa или patch-ab, всегда ссылайтесь на путь и название файла в названиях самих патчей.

Существует альтернативный упрощённый способ создания патчей для существующих файлов. Первые шаги те же самые: создание копии неизменённого файла с расширением .orig и внесение изменений. После этого используйте make makepatch, чтобы обновить файлы с патчами в каталоге files данного порта.

Не помещайте строки RCS в патчи. Subversion будет изменять их при помещении файлов в дерево портов, и когда мы будем их оттуда извлекать, они будут уже другие, поэтому применение патчей окончится неудачей. Строчки RCS предваряются знаком доллара ($), и обычно начинаются с $Id или $RCS.

Использование параметра рекурсии (-r) с командой diff(1) для генерации патчей - это хорошо, но всё же, пожалуйста, смотрите на получающиеся патчи, чтобы убедиться в отсутствии ненужного мусора. В частности, diff-разниц между двумя резервными копиями файлов, файлы Makefile, когда как порт использует Imake или GNU-версию программы configure, и так далее, не нужны, и должны быть удалены. Если было необходимо отредактировать файл configure.in и запустить autoconf для перегенерации configure, не нужно включать файлы diff для configure (они частенько вырастают до нескольких тысяч строк!). Вместо этого задайте USE_AUTOTOOLS=autoconf:261 и включите diff-файл для configure.in.

Старайтесь минимизировать в патчах объём нефункциональных изменений с пустыми символами. В мире Открытого Исходного Кода является распространенным совместное использование проектами больших объемов кодовой базы, но с различными стилями и правилами отступов. При копировании работающей функциональной части из одного проекта для исправления похожей области в другом, будьте аккуратны, пожалуйста: получаемый однострочный патч может указаться полон нефункциональных изменений. Это не только увеличивает размер репозитория Subversion, но также усложняет поиск того, что конкретно вызвало проблему и что вообще поменялось.

Если нужно удалить файл, сделайте это при выполнении цели post-extract, вместо того чтобы оформлять это как часть патча.

Простые перемещения могут быть выполнены непосредственно из Makefile порта с использованием sed(1) в режиме in-place. Это удобно, когда при изменении используется значение переменной:

post-patch:
	@${REINPLACE_CMD} -e 's|for Linux|for FreeBSD|g' ${WRKSRC}/README

Довольно часто в исходных файлах портируемого программного обеспечения используется конвенция CR/LF. Это может стать причиной проблем с дальнейшей упаковкой, предупреждениями компилятора или выполнением скриптов (таких как /bin/sh^M not found). Для быстрого преобразования всех файлов из CR/LF просто в LF добавьте в Makefile порта эту запись:

USES=	dos2unix

Может быть задан точный список преобразуемых файлов:

USES=	dos2unix
DOS2UNIX_FILES=	util.c util.h

Используйте DOS2UNIX_REGEX, чтобы преобразовать группу файлов в разных подкаталогах. Его параметром является регулярное выражение, совместимое с find(1). Подробнее о формате в re_format(7). Такой вариант удобен для преобразования всех файлов заданного расширения. Для примера, преобразуем все исходные файлы, не затрагивая двоичные файлы:

USES=	dos2unix
DOS2UNIX_REGEX=	.*\.([ch]|cpp)

Другим вариантом является использование DOS2UNIX_GLOB, который вызывает find для каждого из перечисленных в нём элементов.

USES=	dos2unix
DOS2UNIX_GLOB=	*.c *.cpp *.h

Этот, и другие документы, могут быть скачаны с http://ftp.FreeBSD.org/pub/FreeBSD/doc/.

По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.

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