Contributed by &a.jkh;, &a.gpalmer;, &a.asami;, &a.obrien; and
&a.hoek;.28 August 1996.
So, now you are interested in making your own port? Great! What follows are some guidelines for creating a new port for
FreeBSD. The bulk of the work is done by
/usr/share/mk/bsd.port.mk, which all port Makefiles include.
Please refer to that file for more details on the inner workings of
the ports collection. Even if you don't hack Makefiles daily, it is
well commented, and you will still gain much knowledge from it.
Note: Only a fraction of the overridable variables
(${..}) are mentioned in this document. Most (if not
all) are documented at the start of bsd.port.mk. This file
uses a non-standard tab setting. Emacs and Vim
should recognize the setting on loading the file. vi or
ex can be set to using the correct value by typing `:set
tabstop=4' once the file has been loaded.
Quick Porting
This section tells you how to do a quick port. In many
cases, it is not enough, but we will see.
First, get the original tarball and put it into
${DISTDIR}, which defaults to
/usr/ports/distfiles.
Note: The following assumes that the software compiled
out-of-the-box, i.e., there was absolutely no change required
for the port to work on your FreeBSD box. If you needed to
change something, you will have to refer to the next section
too.
Writing the Makefile
The minimal Makefile would look something like this:
# New ports collection makefile for: oneko
# Version required: 1.1b
# Date created: 5 December 1994
# Whom: asami
#
# $Id$
#
DISTNAME= oneko-1.1b
CATEGORIES= games
MASTER_SITES= ftp://ftp.cs.columbia.edu/archives/X11R5/contrib/
MAINTAINER= asami@FreeBSD.ORG
MAN1= oneko.1
MANCOMPRESSED= yes
USE_IMAKE= yes
.include
See if you can figure it out. Do not worry about the contents
of the $Id$ line, it will be filled in
automatically by CVS when the port is imported to our main
ports tree. You can find a more detailed example in the section.
Writing the description files
There are three description files that are
required for any port, whether they actually package or not.
They are COMMENT, DESCR, and
PLIST, and reside in the pkg subdirectory.
COMMENT
This is the one-line description of the port. Please
do not include the package name (or version number of the
software) in the comment.
Here is an example:
A cat chasing a mouse all over the screen.
DESCR
This is a longer description of the port. One to a few
paragraphs concisely explaining what the port does is
sufficient. This is not a manual or an
in-depth description on how to use or compile the port!
Please be careful if you are copying from the
README or manpage; too often they are not a
concise description of the port or are in an awkward format
(e.g. manpages have justified spacing). If the ported software
has an official WWW homepage, you should list in here.
It is recommended that you sign the name at the end of
this file, as in:
This is a port of oneko, in which a cat chases a poor mouse all over
the screen.
:
(etc.)
http://www.oneko.org/
- Satoshi
asami@cs.berkeley.edu
PLIST
This file lists all the files installed by the port. It
is also called the `packing list' because the package is
generated by packing the files listed here. The pathnames
are relative to the installation prefix (usually
/usr/local or /usr/X11R6). If you are
using the Here is a small example:
bin/oneko
lib/X11/app-defaults/Oneko
lib/X11/oneko/cat1.xpm
lib/X11/oneko/cat2.xpm
lib/X11/oneko/mouse.xpm
@dirrm lib/X11/oneko
Refer to the pkg_create(1) man page for details
on the packing list. Note that you should list all the
files, but not the name directories, in the list.
Also, if the port creates directories for itself during
installation, make sure to add It is recommended you keep all the filenames in this file
sorted alphabetically. It will make verifying the changes
when you upgrade the port much easier.
Creating the checksum file
Just type `make makesum'. The ports make rules
will automatically generate the file files/md5.
Testing the port
You should make sure that the port rules do exactly what
you want it to do, including packaging up the port. These
are the important points you need to verify:
your port can be installed multiple times using the
your port
after itself upon deinstall
The recommended ordering of tests is:
make installmake packagemake deinstallpkg_add `make package-name`make deinstallmake reinstallmake package
Make sure there aren't any warnings issued in any of the
Checking your port with portlint
Please use portlint to see if your port conforms
to our guidelines. The program is part of the ports collection.
In particular, you may want to check if the is in the right shape
and the is named
appropriately.
Submitting the port
First, make sure you have read the section.
Now that you are happy with your port, the only thing
remaining is to put it in the main FreeBSD ports tree and
make everybody else happy about it too. We do not need
your work/ directory or the pkgname.tgz
package, so delete them now. Next, simply include the
output of `shar `find port_dir`' in a
bug report and send it with the send-pr(1)
program (see for more information about
send-pr). If the uncompressed port is larger than 20KB,
you should compress it into a tarfile and use
uuencode(1) before including it in the bug report
(uuencoded tarfiles are acceptable even if the report is
smaller than 20KB but are not preferred). Be sure to classify
the bug report as category `ports' and class `change-request'.
(Do not mark the report `confidential'!)
One more time, do not include the original source distfile,
the work/ directory, or the package you built with
`make package'!
Note: in the past, we asked you to upload new port
submissions in our ftp site (:<
We will look at your port, get back to you if necessary, and put
it in the tree. Your name will also appear in the list of
`Additional FreeBSD contributors' on the FreeBSD Handbook
and other files. Isn't that great?!? :)Slow Porting
Ok, so it was not that simple, and the port required some
modifications to get it to work. In this section, we will
explain, step by step, how to modify it to get it to work with
the ports paradigm.
How things work
First, this is the sequence of events which occurs when the
user first types `make' in your port's directory,
and you may find that having bsd.port.mk in another
window while you read this really helps to understand it.
But do not worry if you do not really understand what
bsd.port.mk is doing, not many people
do... :>The fetch target is run. The fetch target is
responsible for making sure that the tarball exists
locally in ${DISTDIR}. If fetch cannot
find the required files in ${DISTDIR} it
will look up the URL ${MASTER_SITES},
which is set in the Makefile, as well as our main ftp
site at
where we put sanctioned distfiles as backup. It will then
attempt to
fetch the named distribution file with
${FETCH}, assuming that the requesting
site has direct access to the Internet. If that succeeds,
it will save the file in ${DISTDIR} for
future use and proceed.
The extract target is run. It looks for your port's
distribution file (typically a gzip'd tarball) in
${DISTDIR} and unpacks it into a temporary
subdirectory specified by ${WRKDIR}
(defaults to work).
The patch target is run. First, any patches defined
in ${PATCHFILES} are applied. Second, if
any patches are found in ${PATCHDIR}
(defaults to the patches subdirectory), they are
applied at this time in alphabetical order.
The configure target is run. This can do any one of
many different things.
If it exists, scripts/configure is run.
If ${HAS_CONFIGURE} or
${GNU_CONFIGURE} is set,
${WRKSRC}/configure is run.
If ${USE_IMAKE} is set,
${XMKMF} (default: `xmkmf
-a') is run.
The build target is run. This is responsible for
descending into the ports' private working directory
(${WRKSRC}) and building it. If
${USE_GMAKE} is set, GNU make
will be used, otherwise the system make will be
used.
The above are the default actions. In addition, you can
define targets `pre-<something>' or
`post-<something>', or put scripts with those
names, in the scripts subdirectory, and they will
be run before or after the default actions are done.
For example, if you have a post-extract target
defined in your Makefile, and a file pre-build in
the scripts subdirectory, the
post-extract target will be called after the
regular extraction actions, and the pre-build
script will be executed before the default build rules are
done. It is recommended that you use Makefile targets if
the actions are simple enough, because it will be easier for
someone to figure out what kind of non-default action the
port requires.
The default actions are done by the bsd.port.mk
targets `do-<something>'. For example, the
commands to extract a port are in the target
`do-extract'. If you are not happy with the
default target, you can fix it by redefining the
`do-<something>' target in your Makefile.
Note that the `main' targets (e.g., extract,
configure, etc.) do nothing more than make sure all
the stages up to that one is completed and call the real
targets or scripts, and they are not intended to be
changed. If you want to fix the extraction, fix
do-extract, but never ever touch extract!
Now that you understand what goes on when the user types
`make', let us go through the recommended steps to
create the perfect port.
Getting the original sources
Get the original sources (normally) as a compressed tarball
(<foo>.tar.gz or <foo>.tar.Z)
and copy it into ${DISTDIR}. Always use
mainstream sources when and where you can.
If you cannot find a ftp/http site that is well-connected
to the net, or can only find sites that have irritatingly
non-standard formats, you might want to put a copy on a
reliable ftp or http server that you control (e.g., your
home page). Make sure you set MASTER_SITES to
reflect your choice.
If you cannot find somewhere convenient and reliable to put
the distfile (note that if you are a FreeBSD committer, you
can just put it in the public_html directory on
freefall), we can `house' it ourselves by putting it on
ftp://ftp.freebsd.org/pub/FreeBSD/distfiles/LOCAL_PORTS/
as the last resort. Please refer to this location as
${MASTER_SITE_LOCAL}. Send mail to the &a.ports
if you are not sure what to do.
If your port's distfile changes all the time for no good
reason, consider putting the distfile in your home page and
listing it as the first MASTER_SITES. This will
prevent users from getting `checksum mismatch' errors, and
also reduce the workload of maintainers of our ftp site.
Also, if there is only one master site for the port, it is
recommended that you house a backup at your site and list it
as the second MASTER_SITES.
If your port requires some additional `patches' that are
available on the Internet, fetch them too and put them in
${DISTDIR}. Do not worry if they come from
site other than where you got the main source tarball,
we have a way to handle these situations (see the
description of below).
Modifying the port
Unpack a copy of the tarball in a private directory and
make whatever changes are necessary to get the port to
compile properly under the current version of FreeBSD. Keep
careful track of everything you do, as you will be
automating the process shortly. Everything, including the
deletion, addition or modification of files should be doable
using an automated script or patch file when your port is
finished.
If your port requires significant user
interaction/customization to compile or install, you should
take a look at one of Larry Wall's classic Configure scripts
and perhaps do something similar yourself. The goal of the
new ports collection is to make each port as `plug-and-play'
as possible for the end-user while using a minimum of disk
space.
Note: Unless explicitly stated, patch files, scripts, and
other files you have created and contributed to the FreeBSD
ports collection are assumed to be covered by the standard
BSD copyright conditions.
Patching
In the preparation of the port, files that have been added
or changed can be picked up with a recursive diff for later
feeding to patch. Each set of patches you wish to apply
should be collected into a file named
`patch-<xx>' where <xx>
denotes the sequence in which the patches will be applied --
these are done in alphabetical order, thus
`aa' first, `ab' second and so on. These
files should be stored in ${PATCHDIR}, from
where they will be automatically applied. All patches
should 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-aa and patch-ab both changing
${WRKSRC}/foobar.c).
Configuring
Include any additional customization commands to your
configure script and save it in the
`scripts' subdirectory. As mentioned above, you
can also do this as Makefile targets and/or scripts with the
name pre-configure or post-configure.
Handling user input
If your port requires user input to build, configure or
install, then set IS_INTERACTIVE in your Makefile.
This will allow `overnight builds' to skip your port if the
user sets the variable BATCH in his environment
(and if the user sets the variable INTERACTIVE,
then only those ports requiring interaction are
built).
It is also recommended that if there are reasonable
default answers to the questions, you check the
Configuring the Makefile
Configuring the Makefile is pretty simple, and again we
suggest that you look at existing examples before starting.
Also, there is a in this handbook, so take a look and please follow
the ordering of variables and sections in that template to
make your port easier for others to read.
Now, consider the following problems in sequence as you
design your new Makefile:
The original source
Does it live in ${DISTDIR} as a standard
gzip'd tarball? If so, you can go on to the next step. If
not, you should look at overriding any of the
${EXTRACT_CMD},
${EXTRACT_BEFORE_ARGS},
${EXTRACT_AFTER_ARGS},
${EXTRACT_SUFX}, or
${DISTFILES} variables, depending on how
alien a format your port's distribution file is. (The most
common case is `EXTRACT_SUFX=.tar.Z', when the
tarball is condensed by regular compress, not gzip.)
In the worst case, you can simply create your own
`do-extract' target to override the default, though
this should be rarely, if ever, necessary.
DISTNAME
You should set ${DISTNAME} to be the base
name of your port. The default rules expect the
distribution file list (${DISTFILES}) to be
named
${DISTNAME}${EXTRACT_SUFX}
which, if it is a normal tarball, is going to be
something like:
foozolix-1.0.tar.gz
for a setting of `DISTNAME=foozolix-1.0'.
The default rules also expect the tarball(s) to extract into
a subdirectory called work/${DISTNAME}, e.g.
work/foozolix-1.0/
All this behavior can be overridden, of course; it simply
represents the most common time-saving defaults. For a port
requiring multiple distribution files, simply set
${DISTFILES} explicitly. If only a subset
of ${DISTFILES} are actual extractable
archives, then set them up in
${EXTRACT_ONLY}, which will override the
${DISTFILES} list when it comes to
extraction, and the rest will be just left in
${DISTDIR} for later use.
PKGNAME
If ${DISTNAME} does not conform to our , you should set the ${PKGNAME}
variable to something better. See the abovementioned
guideline for more details.
CATEGORIES
When a package is created, it is put under
/usr/ports/packages/All and links are made from one
or more subdirectories of /usr/ports/packages. The
names of these subdirectories are specified by the variable
${CATEGORIES}. It is intended to make life
easier for the user when he is wading through the pile of
packages on the ftp site or the CD-ROM. Please take a look
at the existing and pick the ones that are suitable for
your port.
This list also determines where in the ports tree the port
is imported. If you put more than one category here, it is
assumed that the port files will be put in the subdirectory
with the name in the first category. See the section for more
discussion about how to pick the right categories.
If your port truly belongs to something that is different
from all the existing ones, you can even create a new
category name. In that case, please send mail to the &a.ports;
to propose a new category.
Note that there is no error checking for category names;
`make package' will happily create a new directory
if you mistype the category name, so be careful!
MASTER_SITES
Record the directory part of the ftp/http-URL pointing at
the original tarball in ${MASTER_SITES}.
Do not forget the trailing slash (/)!
The make macros will try to use this specification for
grabbing the distribution file with ${FETCH}
if they cannot find it already on the system.
It is recommended that you put multiple sites on this list,
preferably from different continents. This will safeguard
against wide-area network problems, and we are even planning
to add support for automatically determining the closest
master site and fetching from there!
If the original tarball is part of one of the following
popular archives: X-contrib, GNU, Perl CPAN, TeX CTAN, or
Linux Sunsite, you refer to those sites in an easy compact
form using MASTER_SITE_XCONTRIB, MASTER_SITE_GNU,
MASTER_SITE_PERL_CPAN, MASTER_SITE_TEX_CTAN, and
MASTER_SITE_SUNSITE. Simply set MASTER_SITE_SUBDIR to the path
with in the archive. Here is an example:
MASTER_SITES= ${MASTER_SITE_XCONTRIB}
MASTER_SITE_SUBDIR= applications
The user can also set the MASTER_SITE_* variables in
/etc/make.conf to override our choices, and use their
favorite mirrors of these popular archives instead.
PATCHFILES
If your port requires some additional patches that are
available by ftp or http, set ${PATCHFILES}
to the names of the files and ${PATCH_SITES}
to the URL of the directory that contains them (the format
is the same as ${MASTER_SITES}).
If the patch is not relative to the top of the source tree
(i.e., ${WKRSRC}) because it contains some
extra pathnames, set ${PATCH_DIST_STRIP}
accordingly. For instance, if all the pathnames in the
patch has an extra `foozolix-1.0/' in front of the
filenames, then set `PATCH_DIST_STRIP=-p1'.
Do not worry if the patches are compressed, they will be
decompressed automatically if the filenames end with
`.gz' or `.Z'.
If the patch is distributed with some other files, such as
documentation, in a gzip'd tarball, you can't just use
${PATCHFILES}. If that is the case, add the
name and the location of the patch tarball to
${DISTFILES} and
${MASTER_SITES}. Then, from the
pre-patch target, apply the patch either by running
the patch command from there, or copying the patch file into
the ${PATCHDIR} directory and calling it
patch-<xx>. (Note the tarball will have been
extracted alongside the regular source by then, so there is
no need to explicitly extract it if it is a regular gzip'd
or compress'd tarball.) If you do the latter, take extra
care not to overwrite something that already exists in that
directory. Also do not forget to add a command to remove
the copied patch in the pre-clean target.
MAINTAINER
Set your mail-address here. Please. :)
For detailed description of the responsibility of maintainers,
refer to section.
Dependencies
Many ports depend on other ports. There are five variables
that you can use to ensure that all the required bits will
be on the user's machine. There are also some pre-supported
dependency variables for common cases, plus a few more to
control the behavior of dependencies.
LIB_DEPENDS
This variable specifies the shared libraries this port
depends on. It is a list of `lib:dir[:target]' tuples
where lib is the name of the shared library, and
dir is the directory in which to find it in case
it is not available, and
LIB_DEPENDS= jpeg.9:${PORTSDIR}/graphics/jpeg:install
will check for a shared jpeg library with major version 9,
and descend into the graphics/jpeg subdirectory
of your ports tree to build and install it if it is not
found. The `${DEPENDS_TARGET} (which defaults to
`lib part is an argument given
to `ldconfig -r | grep -wF'. There shall be no
regular expressions in this variable.
The dependency is checked twice, once from within the
pkg_add will
automatically install it if it is not on the user's
system.
RUN_DEPENDS
This variable specifies executables or files this port
depends on during run-time. It is a list of
`path:dir[:target]' tuples where path is the name
of the executable or file, and dir is the
directory in which to find it in case it is not
available, and `path starts with a slash
(/), it is treated as a file or directory and its
existence is
tested with `test -e'; otherwise, it is assumed
to be an executable, and `which -s' is used to
determine if the program exists in the user's search path.
For example,
RUN_DEPENDS= ${PREFIX}/etc/innd:${PORTSDIR}/news/inn \
wish8.0:${PORTSDIR}/x11-toolkits/tk80
will check if the file or directory `/usr/local/etc/innd'
exists, and build and install it from the
news/inn subdirectory of the ports tree if it is
not found. It will also see if an executable called
`wish8.0' is in your search path, and descend into
the x11-toolkits/tk80 subdirectory of your ports tree to
build and install it if it is not found. (Note that in
this case, `innd' is actually an executable; if
an executable is in a place that is not expected to be in
a normal user's search path, you should use the full
pathname.)
The dependency is checked from within the install
target. Also, the name of the dependency is put in to the
package so that pkg_add will automatically
install it if it is not on the user's system. The
`${DEPENDS_TARGET}.
BUILD_DEPENDS
This variable specifies executables or files this port
requires to build. Like RUN_DEPENDS, it is a
list of `path:dir[:target]' tuples. For example,
BUILD_DEPENDS= unzip:${PORTSDIR}/archivers/unzip
will check for an executable called `unzip', and
descend into the archivers/unzip subdirectory of
your ports tree to build and install it if it is not found.
Note that `build' here means everything from extracting to
compilation. The dependency is checked from within the
extract target. The `${DEPENDS_TARGET}.
FETCH_DEPENDS
This variable specifies executables or files this port
requires to fetch. Like the previous two, it is a list of
`path:dir[:target]' pairs. For example,
FETCH_DEPENDS= ncftp2:${PORTSDIR}/net/ncftp2
will check for an executable called `ncftp2', and
descend into the net/ncftp2 subdirectory of
your ports tree to build and install it if it is not found.
The dependency is checked from within the fetch
target. The `${DEPENDS_TARGET}.
DEPENDS
If there is a dependency that does not fall into either of
the above four categories, or your port requires to have
the source of the other port extracted in addition to
having them installed, then use this variable. This is
a list of `dir[:target]', as there is nothing to check,
unlike the previous four. The `${DEPENDS_TARGET}.
Common dependency variables
Define `USE_XLIB=yes' if your port requires the
X Window System to be installed (it is implied by
USE_IMAKE). Define `USE_GMAKE=yes' if
your port requires GNU USE_AUTOCONF=yes' if your port requires
GNU autoconf to be run. Define `USE_QT=yes' if
your port uses the latest qt toolkit. Use
`USE_PERL5=yes' if your port requires version 5
of the perl language. (The last is especially important
since some versions of FreeBSD has perl5 as part of the
base system while others don't.)
Notes on dependencies
As mentioned above, the default target to call when a
dependency is required is ${DEPENDS_TARGET}. It
defaults to `*_DEPENDS variables
instead of redefining ${DEPENDS_TARGET}.
When you type `make clean', its dependencies are
automatically cleaned too. If you do not wish this to
happen, define the variable To depend on another port unconditionally, it is
customary to use the string `
BUILD_DEPENDS= /nonexistent:${PORTSDIR}/graphics/jpeg:extract
will always descend to the JPEG port and extract it.
Do not use `Building mechanisms
If your package uses GNU make, set
`USE_GMAKE=yes'. If your package uses configure,
set `HAS_CONFIGURE=yes'. If your package uses
GNU GNU_CONFIGURE=yes' (this
implies --prefix=${PREFIX}' for GNU ${CONFIGURE_ARGS}. If your package uses GNU
USE_AUTOCONF=yes'. This
implies If your package is an X application that creates Makefiles
from Imakefiles using imake, then set
`USE_IMAKE=yes'. This will cause the configure
stage to automatically do an xmkmf -a. If the
`-a' flag is a problem for your port, set
`XMKMF=xmkmf'.
If the port uses imake but does not understand the
`install.man' target,
`NO_INSTALL_MANPAGES=yes' should be set. In
addition, the author of the original port should be
shot. :>
If your port's source Makefile has something else than
`all' as the main build target, set
${ALL_TARGET} accordingly. Same goes for
`install' and ${INSTALL_TARGET}.
Special Considerations
There are some more things you have to take into account when
you create a port. This section explains the most common of those.
If your port installs a shared library, add a
post-install target to your Makefile that runs
`${LDCONFIG} -m' on the directory where the new
library is installed (usually ${PREFIX}/lib)
to register it into the shared library cache.
Also, add a matching `@exec /sbin/ldconfig
-m'/`@unexec /sbin/ldconfig -R' pair to your
pkg/PLIST file so that a user who installed the
package can start using the shared library immediately and
deinstallation will not cause the system to still believe
the library is there. These lines should immediately follow
the line for the shared library itself, as in:
lib/libtcl80.so.1
@exec /sbin/ldconfig -m %D/lib
@unexec /sbin/ldconfig -R
Never, ever, ever add a line that says
`ldconfig' without any arguments to your Makefile
or pkg/PLIST. This will reset the shared library cache to
the contents of /usr/lib only, and will royally
screw up the user's machine ("Help, xinit does not run
anymore after I install this port!"). Anybody who does this
will be shot and cut into 65,536 pieces by a rusty knife and
have his liver chopped out by a bunch of crows and will
eternally rot to death in the deepest bowels of hell (not
necessarily in that order)....
ELF support
Since FreeBSD is moving to ELF from 3.0-release onwards,
we need to convert many ports that build shared libraries
to support ELF. Complicating this task is that a 3.0
system can run as both ELF and a.out, and that there will
be one more release (2.2.8) from the 2.2 branch. Below
are the guidelines on how to convert a.out only ports to
support both a.out and ELF compilation.
Some part of this list is only applicable during the
conversion, but will be left here for awhile for reference
in case you have come across some old port you wish to
upgrade.
Moving a.out libraries out of the way
A.out libraries should be moved out of
/usr/local/lib and similar to an `src/Makefile (called from `Format
The ports tree will build packages in the format the
machine is in. This means a.out for 2.2 and a.out or
ELF for 3.0 depending on what `objformat`
returns. Also, once users move a.out libraries
to a subdirectory, building a.out libraries will be
unsupported. (I.e., it may still work if you know what
you are doing, but you are on your own.)
Note: if a port only works for a.out, set
PORTOBJFORMAT
PORTOBJFORMAT=${PORTOBJFORMAT}'. (See comment
on The variable is set using this line:
PORTOBJFORMAT!= test -x /usr/bin/objformat && /usr/bin/objformat || echo aout
in Ports' make processes should use this variable to
decide what to do. However, if the port's
Building shared libraries
The following are differences in handling shared
libraries for a.out and ELF.
Shared library versionsAn ELF shared library
should be called "Linker command linesAssuming `cc
-shared' is used rather than `-Wl,-soname,libfoo.so.M' on the command line
for ELF.
You need to install a symlink libfoo.so ->
libfoo.so.N to make ELF linkers happy. Since
it should be listed in
All port Makefiles are edited to remove minor numbers
from foo\\.1\\.\\(33|40\\)' -> `foo.2'.)
They will be matched using `grep -wF'.
In cases where you really need to install shlibs with
two versions on an ELF system or those with one version
on an a.out system (for instance, ports that install
compatibility libraries for other operating systems),
define the variable
The
${SETENV} OBJFORMAT=${PORTOBJFORMAT} ${LDCONFIG} -m ....
and in
@exec /usr/bin/env OBJFORMAT=%%PORTOBJFORMAT%% /sbin/ldconfig -m ...
@unexec /usr/bin/env OBJFORMAT=%%PORTOBJFORMAT%% /sbin/ldconfig -R
This is to ensure that the correct
If your port needs to build slightly different versions
of packages by having a variable (for instance, resolution
or paper size) take different values, create one
subdirectory per package to make it easier for users to
see what to do, but try to share as many files as possible
between ports. Typically you only need a very short
Makefile in all but one of the directories if you use
variables cleverly. In the sole Makefiles, you can use
${MASTERDIR} to specify the directory
where the rest of the files are. Also, use a variable as
part of
so the packages will have different names.
This will be best demostrated by an example. This is
part of japanese/xdvi300/Makefile:
:
PKGNAME= ja-xdvi${RESOLUTION}-17
:
# default
RESOLUTION?= 300
.if ${RESOLUTION} != 118 && ${RESOLUTION} != 240 && \
${RESOLUTION} != 300 && ${RESOLUTION} != 400
@${ECHO} "Error: invalid value for RESOLUTION: \"${RESOLUTION}\""
@${ECHO} "Possible values are: 118, 240, 300 (default) and 400."
@${FALSE}
.endif
japanese/xdvi300 also has all the regular
patches, package files, etc. If you type `As for other resolutions, this is the xdvi118/Makefile (minus the comments):
RESOLUTION= 118
MASTERDIR= ${.CURDIR}/../xdvi300
.include "${MASTERDIR}/Makefile"
(xdvi240/Makefile and xdvi400/Makefile
are similar). The ${MASTERDIR} definition
tells ${PATCHDIR} and
${PKGDIR} are to be found under
xdvi300/Makefile
and the port will be built with resolution set to 118.
Shared library versions
First, please read our to understand
what to do with shared library versions in general. Do
not blindly assume software authors know what they are
doing; many of them do not. It is very important that
these details are carefully considered, as we have quite a
unique situation where we are trying to have dozens of
potentially incompatible software pairs co-exist.
Careless port imports have caused great trouble regarding
shared libraries in the past (ever wondered why the port
However, if there is a port which is a different version
of the same software already in the tree, the situation is
much more complex. In short, the FreeBSD implementation
does not allow the user to specify to the linker which
version of shared library to link against (the linker will
always pick the highest numbered version). This means, if
there is a Manpages
The pkg/PLIST (this means you must for more).
It also makes the install stage automatically compress or
uncompress manpages depending on the setting of
/etc/make.conf.
To specify whether the manpages are compressed upon
installation, use the If your port anchors its man tree somewhere other than
PREFIX, you can use the MANPREFIX to set
it. Also, if only manpages in certain sections go in a
non-standard place, such as some Perl modules ports, you can
set individual man paths using
MANsectPREFIX (where
sect is one of 1-9, L or N).
If your manpages go to language-specific subdirectories,
set the name of the languages to "" (i.e., English only).
Here is an example that puts it all together.
MAN1= foo.1
MAN3= bar.3
MAN4= baz.4
MANLANG= "" ja
MAN3PREFIX= ${PREFIX}/share/foobar
MANCOMPRESSED= yes
states that six files
${PREFIX}/man/man1/foo.1.gz
${PREFIX}/man/ja/man1/foo.1.gz
${PREFIX}/share/foobar/man/man3/bar.3.gz
${PREFIX}/share/foobar/man/ja/man3/bar.3.gz
${PREFIX}/man/man4/baz.4.gz
${PREFIX}/man/ja/man4/baz.4.gz
are installed by this port.
Ports that require Motif
There are many programs that require a Motif library
(available from several commercial vendors, while there is
a free clone reported to be able to run many applications in
x11-toolkits/lesstif) to compile. Since
it is a popular toolkit and their licenses usually permit
redistribution of statically linked binaries, we have made
special provisions for handling ports that require Motif in a
way that we can easily compile binaries linked either
dynamically (for people who are compiling from the port) or
statically (for people who distribute packages).
REQUIRES_MOTIF
If your port requires Motif, define this variable in the
Makefile. This will prevent people who don't own a copy of
Motif from even attempting to build it.
${MOTIFLIB}
This variable will be set by bsd.port.mk to be the
appropriate reference to the Motif library. Please patch
the source to use this wherever the Motif library is
referenced in the Makefile or Imakefile.
There are two common cases:
If the port refers to the Motif library as
`-lXm' in its Makefile or Imakefile, simply
substitute `${MOTIFLIB}' for it.
If the port uses `XmClientLibs' in its
Imakefile, change it to `${MOTIFLIB}
${XTOOLLIB} ${XLIB}'.
Note that ${MOTIFLIB} (usually) expands to
`-L/usr/X11R6/lib -lXm' or
`/usr/X11R6/lib/libXm.a', so there is no need to
add `-L' or `-l' in front.
X11 fonts
If your port installs fonts for the X window system, put
them in ${X11BASE}/lib/X11/fonts/local. This
directory is new to XFree86 release 3.3.3. If it does not
exist, please create it, and print out a message urging the
user to update their XFree86 to 3.3.3 or newer, or at least
add this directory to the font path in
/etc/XF86Config.
Info files
The new version of texinfo (included in 2.2.2-RELEASE and
onwards) contains a utility called `&dollar{PREFIX}/info/dir file. (Sorry for the length
of this section, but it is imperative to weave all the info
files together. If done correctly, it will produce a
beautiful listing, so please bear with me! First, this is what you (as a porter) need to know:
% install-info --help
install-info [OPTION]... [INFO-FILE [DIR-FILE]]
Install INFO-FILE in the Info directory file DIR-FILE.
Options:
--delete Delete existing entries in INFO-FILE;
don't insert any new entries.
:
--entry=TEXT Insert TEXT as an Info directory entry.
:
--section=SEC Put this file's entries in section SEC of the directory.
:
Note that this program will not actually Here's a seven-step procedure to convert ports to use
editors/emacs as an
example.
Look at the texinfo sources and make a patch to insert
--- ./man/vip.texi.org Fri Jun 16 15:31:11 1995
+++ ./man/vip.texi Tue May 20 01:28:33 1997
@@ -2,6 +2,10 @@
@setfilename ../info/vip
@settitle VIP
+@dircategory The Emacs editor and associated tools
+@direntry
+* VIP: (vip). A VI-emulation for Emacs.
+@end direntry
@iftex
@finalout
:
The format should be self-explanatory. Many authors leave
a Note that you can put only one info entry per file because
of a bug in `install-info --delete' that deletes
only the first entry if you specify multiple entries in the
You can give the three
places (japanese/skk for examples on how to do this).
Go back to the port directory and do a `make clean;
make' and verify that the info files are regenerated
from the texinfo sources. Since the texinfo sources are
newer than the info files, they should be rebuilt when you
type
--- ./Makefile.in.org Mon Aug 19 21:12:19 1996
+++ ./Makefile.in Tue Apr 15 00:15:28 1997
@@ -184,7 +184,7 @@
# Subdirectories to make recursively. `lisp' is not included
# because the compiled lisp files are part of the distribution
# and you cannot remake them without installing Emacs first.
-SUBDIR = lib-src src
+SUBDIR = lib-src src man
# The makefiles of the directories in $SUBDIR.
SUBDIR_MAKEFILES = lib-src/Makefile man/Makefile src/Makefile oldXMenu/Makefile lwlib/Makefile
--- ./man/Makefile.in.org Thu Jun 27 15:27:19 1996
+++ ./man/Makefile.in Tue Apr 15 00:29:52 1997
@@ -66,6 +66,7 @@
${srcdir}/gnu1.texi \
${srcdir}/glossary.texi
+all: info
info: $(INFO_TARGETS)
dvi: $(DVI_TARGETS)
The second hunk was necessary because the default target in
the /usr/share/info
(that patch is not shown here).
If there is a place in the
--- ./Makefile.in.org Mon Aug 19 21:12:19 1996
+++ ./Makefile.in Mon Apr 14 23:38:07 1997
@@ -368,14 +368,8 @@
if [ `(cd ${srcdir}/info && /bin/pwd)` != `(cd ${infodir} && /bin/pwd)` ]; \
then \
(cd ${infodir}; \
- if [ -f dir ]; then \
- if [ ! -f dir.old ]; then mv -f dir dir.old; \
- else mv -f dir dir.bak; fi; \
- fi; \
cd ${srcdir}/info ; \
- (cd $${thisdir}; ${INSTALL_DATA} ${srcdir}/info/dir ${infodir}/dir); \
- (cd $${thisdir}; chmod a+r ${infodir}/dir); \
for f in ccmode* cl* dired-x* ediff* emacs* forms* gnus* info* message* mh-e* sc* vip*; do \
(cd $${thisdir}; \
${INSTALL_DATA} ${srcdir}/info/$$f ${infodir}/$$f; \
chmod a+r ${infodir}/$$f); \
(This step is only necessary if you are modifying an
existing port.) Take a look at pkg/PLIST and
delete anything that is trying to patch up
info/dir. They may be in pkg/INSTALL or
some other file, so search extensively.
Index: pkg/PLIST
===================================================================
RCS file: /usr/cvs/ports/editors/emacs/pkg/PLIST,v
retrieving revision 1.15
diff -u -r1.15 PLIST
--- PLIST 1997/03/04 08:04:00 1.15
+++ PLIST 1997/04/15 06:32:12
@@ -15,9 +15,6 @@
man/man1/emacs.1.gz
man/man1/etags.1.gz
man/man1/ctags.1.gz
-@unexec cp %D/info/dir %D/info/dir.bak
-info/dir
-@unexec cp %D/info/dir.bak %D/info/dir
info/cl
info/cl-1
info/cl-2
Add a
Index: Makefile
===================================================================
RCS file: /usr/cvs/ports/editors/emacs/Makefile,v
retrieving revision 1.26
diff -u -r1.26 Makefile
--- Makefile 1996/11/19 13:14:40 1.26
+++ Makefile 1997/05/20 10:25:09 1.28
@@ -20,5 +20,11 @@
post-install:
.for file in emacs-19.34 emacsclient etags ctags b2m
strip ${PREFIX}/bin/${file}
.endfor
+ if [ ! -f ${PREFIX}/info/dir ]; then \
+ ${SED} -ne '1,/Menu:/p' /usr/share/info/dir > ${PREFIX}/info/dir; \
+ fi
+.for info in emacs vip viper forms gnus mh-e cl sc dired-x ediff ccmode
+ install-info ${PREFIX}/info/${info} ${PREFIX}/info/dir
+.endfor
.include
Do not use anything other than /usr/share/info/dir
and the above command to create a new info file. In fact,
I'd add the first three lines of the above patch to
Edit info/dir with
Index: pkg/PLIST
===================================================================
RCS file: /usr/cvs/ports/editors/emacs/pkg/PLIST,v
retrieving revision 1.15
diff -u -r1.15 PLIST
--- PLIST 1997/03/04 08:04:00 1.15
+++ PLIST 1997/05/20 10:25:12 1.17
@@ -16,7 +14,15 @@
man/man1/etags.1.gz
man/man1/ctags.1.gz
+@unexec install-info --delete %D/info/emacs %D/info/dir
:
+@unexec install-info --delete %D/info/ccmode %D/info/dir
info/cl
info/cl-1
@@ -87,6 +94,18 @@
info/viper-3
info/viper-4
+@exec [ -f %D/info/dir ] || sed -ne '1,/Menu:/p' /usr/share/info/dir > %D/info/dir
+@exec install-info %D/info/emacs %D/info/dir
:
+@exec install-info %D/info/ccmode %D/info/dir
libexec/emacs/19.34/i386--freebsd/cvtmail
libexec/emacs/19.34/i386--freebsd/digest-doc
Note that the `@unexec install-info --delete'
commands have to be listed before the info files themselves
so they can read the files. Also, the `@exec
install-info' commands have to be after the info files
and the and admire your
work. The
There are some tricks we haven't mentioned yet about the