(Originally published at **bitsonline.com, ****)
FreeBSD Ports and Packages System Explained
Bill Swingle " >
What is the ports collection?
If you've ever toyed around with one of the many Unix-based operating
systems, chances are you've had to compile a thing or two from source
code. Chances are that you've also encountered source code that would
not compile on your system, due to it being written for a different
Unix operating system, to poor coding on the author's part, or just
because your system is missing other programs the compile depends on.
The FreeBSD ports/packages system attempts to address all of these
issues and make third party application installation a breeze.
As an operating system, FreeBSD has a lot in common with most other
Unix operating systems. This means that there are a lot of
applications that, though originally written for another OS, such as
Linux, will compile and run with little or no difficulty on FreeBSD.
This is where the ports system comes into play. The ports system is
really nothing more than a few files per application that describe how
that application has to be modified to compile, install and run on
FreeBSD. Even the downloading of the original application is handled
by the ports system. Installing new applications comes down to running
one command, "make install".
How does it work?
Let's look at a sample port build to get a better idea of how the
process plays out.
First you must cd into the directory for the application that you want
to install. All of the 3100+ ports are divided into categories based
on what kind of program it is. In this example we're going to install
a popular GUI-based IRC client called xchat:
# cd /usr/ports/irc/xchat
This directory contains whatever source code patches are needed to get
the program to compile and a Makefile that controls where the original
source is downloaded from, how the patches are applied, how the
program is compiled and where it is installed. It's hard to believe,
but all of this is done by typing make install.
# make install
>> xchat-1.4.0.tar.bz2 doesn't seem to exist on this system.
>> Attempting to fetch from http://xchat.org/files/source/1.4/.
Receiving xchat-1.4.0.tar.bz2 (333132 bytes): 100%
333132 bytes transferred in 4.1 seconds (79.76 Kbytes/s)
Extracting for xchat-1.4.0
>> Checksum OK for xchat-1.4.0.tar.bz2.
xchat-1.4.0 depends on executable: bzip2 - found
xchat-1.4.0 depends on executable: gmake - found
xchat-1.4.0 depends on shared library: gtk12.2 - found
xchat-1.4.0 depends on shared library: Imlib.5 - found
xchat-1.4.0 depends on shared library: X11.6 - found
Patching for xchat-1.4.0
Configuring for xchat-1.4.0
...
[configure output snipped]
...
Building for xchat-1.4.0
...
[compilation snipped]
...
Installing for xchat-1.4.0
xchat-1.4.0 depends on shared library: gtk12.2 - found
xchat-1.4.0 depends on shared library: Imlib.5 - found
xchat-1.4.0 depends on shared library: X11.6 - found
...
[install routines snipped]
...
Generating temporary packing list
Installing xchat docs in /usr/X11R6/share/doc/xchat
Registering installation for xchat-1.4.0
#
Xchat is now installed. No messing with patches, crazy command line
options, or even having to find the right ftp server to get the
download from. You'll notice that the port even checked to see that
several other applications that it depends on were already installed.
In this case the dependencies were all already installed but, if it
hadn't found any of them, it would have gone and installed them, as
well using those applications entries in the ports system.
What do packages have to do with all this?
Well, if you're like me, every unix system that you own/run has a few
applications in common that you install as soon as the base operating
system is installed. I, generally, install the bash shell, the less
pager, the vim editor, and ssh. Having to compile these things over
and over again gets to be a bit of a pain if not merely time
consuming.
The ports system is tightly associated with the package system. Once
you've built a port from source and installed it on the system, you
can make a package out of it with the make package command.
Make sure you're in the same directory that you ran make install from.
# cd /usr/ports/irc/xchat
# make package
Building package for xchat-1.4.0
Creating package /usr/ports/irc/xchat/xchat-1.4.0.tgz
Registering depends: gettext-0.10.35 glib-1.2.6 gtk-1.2.6 imlib-1.9.8
jpeg-6b libungif-4.1.0 png-1.0.5 tiff-3.5.4.
Creating gzip'd tar ball in '/usr/ports/irc/xchat/xchat-1.4.0.tgz'
#
Once again, the port makes sure that you have the correct dependencies
and then it takes all of the files that were installed when you did a
make install and puts them into a package. When make package is
finished, it leaves you with a tarball called, in this case,
xchat-1.4.0.tgz. This tarball contains all of the binaries that you
just compiled from source. You can now take this package to another
FreeBSD system and use the pkg_add command to install it without
having to recompile it again.
Normally pkg_add, when used without any options, will not print
anything if it successfully installs the package. In the example
below, we're running pkg_add with the -v option so you can get a
little better idea of what it's actually doing.
# pkg_add -v ./xchat-1.4.0.tgz
Requested space: 968680 bytes,
free space: 111746048 bytes in /var/tmp/instmp.a30314
Package `xchat-1.4.0' depends on `gettext-0.10.35'. - already installed.
Package `xchat-1.4.0' depends on `glib-1.2.6'. - already installed.
Package `xchat-1.4.0' depends on `gtk-1.2.6'. - already installed.
Package `xchat-1.4.0' depends on `imlib-1.9.8'. - already installed.
Package `xchat-1.4.0' depends on `jpeg-6b'. - already installed.
Package `xchat-1.4.0' depends on `libungif-4.1.0'. - already installed.
Package `xchat-1.4.0' depends on `png-1.0.5'. - already installed.
Package `xchat-1.4.0' depends on `tiff-3.5.4'. - already installed.
extract: Package name is xchat-1.4.0
...
[ extraction details snipped ]
...
Attempting to record package into /var/db/pkg/xchat-1.4.0..
Attempting to record dependency on package `gettext-0.10.35'
Attempting to record dependency on package `glib-1.2.6'
Attempting to record dependency on package `gtk-1.2.6'
Attempting to record dependency on package `imlib-1.9.8'
Attempting to record dependency on package `jpeg-6b'
Attempting to record dependency on package `libungif-4.1.0'
Attempting to record dependency on package `png-1.0.5'
Attempting to record dependency on package `tiff-3.5.4'
Package xchat-1.4.0 registered in /var/db/pkg/xchat-1.4.0
The fun doesn't stop there, though. Within the FreeBSD project there
is a whole team of people whose main responsibility is maintaining
these ports and packages. In fact, the project has a cluster of nine
servers whose sole purpose in life is to build all 3100+ ports each
night to make sure that they still compile correctly. This testing
procedure also includes testing the package facilities of each port
which, of course, produces a viable package. These packages that are
built each night are available on the main FreeBSD ftp server. I know
what you're thinking, "Oh great, now I have to go digging through a
gigantic ftp server to find these easy-to-install packages". Nope,
this functionality is already built into pkg_add with the -r flag.
From the pkg_add(1) man page:
-r Use the remote fetching feature. This will determine the
appropriate objformat and release and then fetch and
install the package.
So, not only will pkg_add install the package for you, it will also
download the newest version for your platform. Because you're getting
the newest version when using the -r option you don't have to worry
about version numbers. In this example, as in all the others, pkg_add
checks for dependencies. This time it finds one that is not installed
so it downloads and installs it for you.
# pkg_add -r xchat
Fetching
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-current/Latest/xchat.
tgz ... Done.
Fetching
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-current/All/gtk-1.2.7.tgz ... Done.
#
In fact, you can specify multiple packages to install at the same
time. When I bring up a new FreeBSD system, I run this command:
# pkg_add -r bash less vim
Fetching
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-current/Latest/bash.tgz... Done.
updating /etc/shells
Fetching ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-current/Latest/less.tgz... Done.
Fetching ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-current/Latest/vim.tgz... Done.
#
Removing Installed Ports
Since installing new applications is so easy, using the ports/packages
system is a great way to try out new applications. Of course, at some
point you're going to want to remove an application that you've
installed using this method. Depending how you installed the
application, you can remove it one of two ways.
If you installed the application by compiling it with the make install
command, you have to use the make deinstall command:
# cd /usr/ports/irc/xchat
# make deinstall
Deinstalling for xchat-1.4.0
#
If you installed the application using the pkg_add command you must
use the pkg_delete command:
# pkg_delete -v xchat-1.4.0
Change working directory to /usr/X11R6
Delete file /usr/X11R6/bin/xchat
...
[ deleted file list snipped ]
...
When Good Ports Go Bad
Each of the 3100+ ports in the ports collection has a maintainer who
is responsible for making sure that the port stays up to date with the
current version of the application. This includes making sure that the
code continues to compile and that the original distributions are
still available in the same location. The nightly testing of all of
the ports generates a report for all of the maintainers letting them
know when there are problems with their ports. Of course these
maintainers are only human so sometimes these problems don't get fixed
right away.
The most common problem is when the original distribution has moved to
another location. Without knowing where it has moved to, the ports
system can't download it to build the application in the first place.
Anytime you have a problem building any of the ports, you should
report it to the port maintainer or to the
[2]*******-*****@*******.*** mailing list. The port maintainer is
listed in the Makefile in each port and also on the [3]FreeBSD Ports
website. Please include as much detail as possible when reporting a
problem.
References
1. mailto:******@*******.***
2. mailto:*******-*****@*******.***
3. http://www.freebsd.org/ports/