4.4 Patching

In the preparation of the port, files that have been added or changed can be picked up with a diff(1) for later feeding to patch(1). Each patch you wish to apply should be saved into a file named patch-* where * indicates the pathname of the file that is patched, such as patch-Imakefile or patch-src-config.h. These files should be stored in PATCHDIR (usually files/, from where they will be automatically applied. All patches must be relative to WRKSRC (generally the directory your port's tarball unpacks itself into, that being where the build is done). To make fixes and upgrades easier, you should avoid having more than one patch fix the same file (e.g., patch-file and patch-file2 both changing WRKSRC/foobar.c). Note that if the path of a patched file contains an underscore (_) character, the patch needs to have two underscores instead in its name. 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 your patches. Do not use any other characters besides them. Do not name your patches like patch-aa or patch-ab etc, always mention the path and file name in patch names.

Do not put RCS strings in patches. SVN 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 take a look at the resulting patches to make sure you do not have any 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 you had 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!); define USE_AUTOTOOLS=autoconf:261 and take the diffs of configure.in.

Also, try to minimize the amount of non-functional whitespace changes in your 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. If you take 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 SVN repository but makes it hard to find out what exactly caused the problem and what you changed at all.

If you had to delete a file, then you can do it in the post-extract target rather than as part of the patch.

Simple replacements can be performed directly from the port Makefile using the in-place mode of sed(1). This is very useful when you need to patch in a variable value. Example:

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

Quite often, there is a situation when the software being ported, especially if it is primarily developed on Windows®, uses the CR/LF convention for most of its source files. This may cause problems with further patching, compiler warnings, scripts execution (/bin/sh^M not found), etc. To quickly convert all files from CR/LF to just LF, add USE_DOS2UNIX=yes to the port Makefile. A list of files to convert can be specified:

USE_DOS2UNIX=	util.c util.h

If you want to convert a group of files across subdirectories, DOS2UNIX_REGEX can be used. Its argument is a find 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 all source code files leaving binary files intact:

USE_DOS2UNIX=	yes
DOS2UNIX_REGEX=	.*\.(c|cpp|h)

If you want to create a patch file based off of an existing file, you can copy it with an .orig extension, and then modify the original one. The makepatch target will write out an appropriate patch file to the files directory of the port.

For questions about the FreeBSD ports system, e-mail <[email protected]>.
For questions about this documentation, e-mail <[email protected]>.