4.4. Patching

In the preparation of the port, files that have been added or changed can be recorded with diff(1) for later feeding to patch(1). Doing this with a typical file involves saving a copy of the original file before making any changes.

% cp file file.orig

4.4.1. Automatic Patch Generation

When all the files have been modified, use make makepatch from the port directory to write updated patch files to the files directory of the port.

4.4.2. Manual Patch Generation

Patches are saved into files named patch-* where * indicates the pathname of the file that is patched, such as patch-Imakefile or patch-src-config.h.

After the file has been modified, diff(1) is used to record the differences between the original and the modified version. -u causes diff(1) to produce unified diffs, the preferred form.

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

When generating patches for new, added files, -N is added to tell diff(1) to treat the non-existent original file as if it existed but was empty:

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

Patch files are stored in PATCHDIR (usually files/, from where they will be automatically applied. All patches must be relative to WRKSRC (generally the directory the port's tarball unpacks itself into, that being where the build is done). To make fixes and upgrades easier, avoid having more than one patch fix the same file (that is, patch-file and patch-file2 both changing WRKSRC/foobar.c). Note that in the path of a patched file the / are to be replaced with two underscores __. For example, to patch a file named src/freeglut_joystick.c, the corresponding patch should be named patch-src__freeglut_joystick.c.

Please only use characters [-+._a-zA-Z0-9] for naming patches. Do not use any other characters besides them. Do not name patches like patch-aa or patch-ab, always mention the path and file name in patch names.

Do not put RCS strings in patches. Subversion will mangle them when we put the files into the ports tree, and when we check them out again, they will come out different and the patch will fail. RCS strings are surrounded by dollar ($) signs, and typically start with $Id or $RCS.

Using the recurse (-r) option to diff(1) to generate patches is fine, but please look at the resulting patches to make sure there is no unnecessary junk in there. In particular, diffs between two backup files, Makefiles when the port uses Imake or GNU configure, etc., are unnecessary and should be deleted. If it was necessary to edit configure.in and run autoconf to regenerate configure, do not take the diffs of configure (it often grows to a few thousand lines!). Instead, define USE_AUTOTOOLS=autoconf:261 and take the diffs of configure.in.

4.4.3. General Rules for Patching

Try to minimize the amount of non-functional whitespace changes in patches. It is common in the Open Source world for projects to share large amounts of a code base, but obey different style and indenting rules. When taking a working piece of functionality from one project to fix similar areas in another, please be careful: the resulting line patch may be full of non-functional changes. It not only increases the size of the Subversion repository but makes it hard to find out what exactly caused the problem and what was changed at all.

If a file must be deleted, do it in the post-extract target rather than as part of the patch.

4.4.4. Simple Automatic Replacements

Simple replacements can be performed directly from the port Makefile using the in-place mode of sed(1). This is useful when changes use the value of a variable:

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

Quite often, software being ported uses the CR/LF convention in source files. This may cause problems with further patching, compiler warnings, or script execution (like /bin/sh^M not found.) To quickly convert all files from CR/LF to just LF, add this entry to the port Makefile:

USES=	dos2unix

A list of specific files to convert can be given:

USES=	dos2unix
DOS2UNIX_FILES=	util.c util.h

Use DOS2UNIX_REGEX to convert a group of files across subdirectories. Its argument is a find(1)-compatible regular expression. More on the format is in re_format(7). This option is useful for converting all files of a given extension. For example, convert all source code files, leaving binary files intact:

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

A similar option is DOS2UNIX_GLOB, which invokes find for each element listed in it.

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

All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.