pkg
Subdirectory
There are some more things you have to take into account when you create a port. This section explains the most common of those.
ldconfig
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)....
Since FreeBSD moved to ELF with the 3.0-RELEASE, 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 we wish to unoffically support the 2.2 as long as possible. 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.
A.out libraries should be moved out of
/usr/local/lib
and similar to an `aout
'
subdirectory. (If you don't move them out of the way,
ELF ports will happily overwrite a.out libraries.) The
`move-aout-libs
' target in the 3.0-CURRENT
src/Makefile
(called from `aout-to-elf'
)
will do this for you. It will only move a.out libs so
it is safe to call it on a system with both ELF and
a.out libs in the standard directories.
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
BROKEN_ELF
to a string describing the reason why.
Such ports will be skipped during a build on an ELF
system.
bsd.port.mk
will set PORTOBJFORMAT
to
`aout
' or `elf
' and export it in the
environments CONFIGURE_ENV
, SCRIPTS_ENV
and
MAKE_ENV
. (It's always going to be `aout
' in
2.2-STABLE). It is also passed to PLIST_SUB
as
`PORTOBJFORMAT=${PORTOBJFORMAT}
'. (See comment
on ldconfig
lines below.)
The variable is set using this line:
PORTOBJFORMAT!= test -x /usr/bin/objformat && /usr/bin/objformat || echo aout
in bsd.port.mk
.
Ports' make processes should use this variable to
decide what to do. However, if the port's
configure
script already automatically detects an
ELF system, it is not necessary to refer to
PORTOBJFORMAT
.
The following are differences in handling shared libraries for a.out and ELF.
An ELF shared library
should be called "libfoo.so.M
" where M
is
the single version number, and an a.out library should
be called "libfoo.so.M.N
" where M
is the
major version and N
is the the minor version
number. Do not mix those; never install an ELF
shared library called "libfoo.so.N.M
" or an a.out
shared library (or symlink) called "libfoo.so.N
".
Assuming `cc
-shared
' is used rather than `ld
' directly,
the only difference is that you need to add
`-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 PLIST
too, and it won't hurt
in the a.out case (some ports even require the link for
dynamic loading), you should just make this link
regardless of the setting of PORTOBJFORMAT
.
LIB_DEPENDS
All port Makefiles are edited to remove minor numbers
from LIB_DEPENDS
, and also to have the regexp
support removed. (E.g.,
`foo\\.1\\.\\(33|40\\)
' -> `foo.2
'.)
They will be matched using `grep -wF
'.
PLIST
PLIST
should contain the short (ELF) shlib names
if the a.out minor number is zero, and the long (a.out)
names otherwise. bsd.port.mk
will automatically
add `.0
' to the end of short shlib lines if
PORTOBJFORMAT
equals aout
, and will delete the
minor number from long shlib names if PORTOBJFORMAT
equals elf
.
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 NO_FILTER_SHLIBS
. This will
turn off the editing of PLIST
mentioned in the
previous paragraph.
ldconfig
The ldconfig
line in Makefiles should read:
${SETENV} OBJFORMAT=${PORTOBJFORMAT} ${LDCONFIG} -m ....
and in PLIST
:
@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 ldconfig
will be
called depending on the format of the package, not the
default format of the system.
MASTERDIR
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
PKGNAME
so the packages will have different names.
This will be best demonstrated 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 `make
'
there, it will take the default value for the resolution
(300) and build the port normally.
As for other resolutions, this is the entire
xdvi118/Makefile
(minus the comments):
RESOLUTION= 118
MASTERDIR= ${.CURDIR}/../xdvi300
.include "${MASTERDIR}/Makefile"
(xdvi240/Makefile
and xdvi400/Makefile
are similar). The ${MASTERDIR}
definition
tells bsd.port.mk
that the regular set of
subdirectories like ${PATCHDIR}
and
${PKGDIR}
are to be found under
xdvi300
. The RESOLUTION=118
line will override
the RESOLUTION?=300
line in xdvi300/Makefile
and the port will be built with resolution set to 118.
First, please read our
policy on shared library versioning 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
jpeg-6b
has a shared library version of `9.0'?).
If in doubt, send a message to the FreeBSD ports mailing list
<freebsd-ports@FreeBSD.ORG>
. Most of the
time, your job ends by determining the right shared
library version and making appropriate patches to
implement it.
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 libfoo.so.3.2
and libfoo.so.4.0
in
the system, there is no way to tell the linker to link a
particular application to libfoo.so.3.2
. It is
essentially completely overshadowed in terms of
compilation-time linkage. In this case, the only solution
is to rename the `base' part of the shared library. For
instance, change libfoo.so.4.0
to
libfoo4.so.1.0
so both version 3.2 and 4.0 can be
linked from other ports.
The MAN[1-9LN]
variables will automatically add any
manpages to pkg/PLIST
(this means you must not
list manpages in the PLIST
-- see
generating PLIST for more).
It also makes the install stage automatically compress or
uncompress manpages depending on the setting of
NOMANCOMPRESS
in /etc/make.conf
.
To specify whether the manpages are compressed upon
installation, use the MANCOMPRESSED
variable. This
variable can take three values, `yes
', `no
' and
`maybe
'. `yes
' means manpages are already
installed compressed, `no
' means they are not, and `maybe
'
means the software already respects the value of
NOMANCOMPRESS
so bsd.port.mk
does not have to do
anything special.
MANCOMPRESSED
is automatically set to `yes
' if
USE_IMAKE
is set and NO_INSTALL_MANPAGES
is not
set, and to `no
' otherwise. You don't have to
explicitly define it unless the default is not suitable for
your port.
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 MANLANG
. The value of
this variable defaults 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.
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).
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.
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:
-lXm
' in its Makefile or Imakefile, simply
substitute `${MOTIFLIB}
' for it.
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.
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
.
The new version of texinfo (included in 2.2.2-RELEASE and
onwards) contains a utility called `install-info
' to add
and delete entries to the `dir
' file. If your port
installs any info documents, please follow these instructions
so your port/package will correctly update the user's
${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 install
info files; it merely inserts or deletes entries in the
dir
file.
Here's a seven-step procedure to convert ports to use
install-info
. I will use editors/emacs
as an
example.
@dircategory
and @direntry
statements to files
that don't have them. This is part of my patch:
--- ./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 dir
file in the source tree that contains all the
entries you need, so look around before you try to write
your own. Also, make sure you look into related ports and
make the section names and entry indentations consistent (we
recommend that all entry text start at the 4th tab stop).
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
@direntry
section.
You can give the dir
entries to install-info
as
arguments (--section
and --entry
) instead of
patching the texinfo sources. I do not think this is a good
idea for ports because you need to duplicate the same
information in three places (Makefile
and
@exec
/@unexec
of PLIST
; see below). However,
if you have a Japanese (or other multibyte encoding) info
files, you will have to use the extra arguments to
install-info
because makeinfo
can't handle those
texinfo sources. (See Makefile
and PLIST
of
japanese/skk
for examples on how to do this).
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 make
; but many Makefile
s don't include
correct dependencies for info files. In emacs' case, I had
to patch the main Makefile.in
so it will descend into
the man
subdirectory to rebuild the info pages.
--- ./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 man
subdir is called info
, while the
main Makefile wants to call all
. I also deleted the
installation of the info
info file because we already
have one with the same name in /usr/share/info
(that patch is not shown here).
Makefile
that is
installing the dir
file, delete it. Your port may not
be doing it. Also, remove any commands that are otherwise
mucking around with the dir
file.
--- ./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); \
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
post-install
target to the Makefile to create
a dir
file if it is not there. Also, call
install-info
with the installed info files.
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 <bsd.port.mk>
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
bsd.port.mk
if you (the porter) wouldn't have to do it
in PLIST
by yourself anyway.
PLIST
and add equivalent @exec
statements
and also @unexec
for pkg_delete
. You do not need
to delete info/dir
with @unexec
.
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 @exec
command that creates the the dir
file.
:)
Check the dir
file before and after each
step.pkg
Subdirectory