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
using a .orig
suffix.
%
cp
file
file
.orig
After all changes have been made, cd
back
to the port directory. Use make makepatch
to
generate updated patch files in the files
directory.
Use BINARY_ALIAS
to substitute
hardcoded commands during the build and avoid patching
build files. See Section 5.17, “Use BINARY_ALIAS
to Rename Commands
Instead of Patching the Build” for
more information.
Patch files are stored in PATCHDIR
,
usually files/
, from where they will be
automatically applied. All patches must be relative to
WRKSRC
. Typically
WRKSRC
is a subdirectory of
WRKDIR
, the directory where the distfile is
extracted. Use make -V WRKSRC
to see the
actual path. The patch names are to follow these
rules:
Avoid having more than one patch modify the same file.
For example, having both
patch-foobar.c
and
patch-foobar.c2
making changes to
${WRKSRC}/foobar.c
makes them fragile
and difficult to debug.
When creating names for patch files, replace each
underscore (_
) with two underscores
(__
) and each slash
(/
) with one underscore
(_
). For example, to patch a file
named src/freeglut_joystick.c
, name
the corresponding patch
patch-src_freeglut__joystick.c
. Do
not name patches like patch-aa
or
patch-ab
. Always use the path and
file name in patch names. Using make
makepatch
automatically generates the correct
names.
A patch may modify multiple files if the changes are
related and the patch is named appropriately. For
example,
patch-add-missing-stdlib.h
.
Only use characters [-+._a-zA-Z0-9]
for naming patches. In particular, do not use
::
as a path separator,
use _
instead.
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 patch may be full of non-functional changes. It not only increases the size of the ports 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.
Manual patch creation is usually not necessary. Automatic patch generation as described earlier in this section is the preferred method. However, manual patching may be required occasionally.
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
.origfile
> patch-pathname-file
When generating patches for new, added files,
-N
is used to tell diff(1) to treat the
non-existent original file as if it existed but was
empty:
%
diff -u -N
newfile
.orignewfile
> patch-pathname-newfile
Do not add $FreeBSD$
RCS
strings in patches. When patches are added to the
Subversion repository with
svn add
, the
fbsd:nokeywords
property is set to
yes
automatically so keywords in the patch
are not modified when committed. The property can be added
manually with svn propset fbsd:nokeywords yes
.files...
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,
Makefile
s when the port uses
Imake
or GNU configure
,
etc., are unnecessary and have to 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
USES=autoreconf
and take the
diffs of configure.in
.
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|/usr/local|${PREFIX}|g' ${WRKSRC}/Makefile
Only use sed(1) to replace variable content. You must use patch files instead of sed(1) to replace static content.
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 runs find
for each element listed
in it.
USES= dos2unix DOS2UNIX_GLOB= *.c *.cpp *.h
The base directory for the conversion can be set. This is useful when there are multiple distfiles and several contain files which require line-ending conversion.
USES= dos2unix DOS2UNIX_WRKSRC= ${WRKDIR}
Some ports need patches that are only applied for specific
FreeBSD versions or when a particular option is enabled or
disabled. Conditional patches are specified by placing the
full paths to the patch files in
EXTRA_PATCHES
.
.include <bsd.port.options.mk> # Patch in the iconv const qualifier before this .if ${OPSYS} == FreeBSD && ${OSVERSION} < 1100069 EXTRA_PATCHES= ${PATCHDIR}/extra-patch-fbsd10 .endif .include <bsd.port.mk>
When an option
requires a patch, use
and
opt
_EXTRA_PATCHES
to make the patch conditional on the
opt
_EXTRA_PATCHES_OFF
option.
See Section 5.13.3.11, “Generic Variables Replacement,
opt
and
OPT
_VARIABLE
” for more
information.OPT
_VARIABLE
_OFF
OPTIONS_DEFINE= FOO BAR FOO_EXTRA_PATCHES= ${PATCHDIR}/extra-patch-foo BAR_EXTRA_PATCHES_OFF= ${PATCHDIR}/extra-patch-bar.c \ ${PATCHDIR}/extra-patch-bar.h
EXTRA_PATCHES
With a
DirectorySometime, there are many patches that are needed for a
feature, in this case, it is possible to point
EXTRA_PATCHES
to a directory, and it will
automatically apply all files named
patch-
in
it.*
Create a subdirectory in
${PATCHDIR}
, and move the patches in
it. For example:
%
ls -l
-rw-r--r-- 1 root wheel 350 Jan 16 01:27 patch-Makefile.in -rw-r--r-- 1 root wheel 3084 Jan 18 15:37 patch-configurefiles/foo-patches
Then add this to the Makefile
:
OPTIONS_DEFINE= FOO FOO_EXTRA_PATCHES= ${PATCHDIR}/foo-patches
The framework will then use all the files named
patch-
in
that directory.*
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/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>.