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