Package Management

This is a pretty big topic to cover and this is in no way intended to be an all-inclusive guide to package management on FreeBSD. Rather, think of it as an "intro" to package management. The first section is on installing applications in FreeBSD, while the second deals with removing them. Finally, the last section deals with upgrading your existing software packages.

Installing software in FreeBSD
Creating binary packages of installed software
Finding/listing installed software in FreeBSD
Removing software in FreeBSD
Upgrading software in FreeBSD

Installing software in FreeBSD

There are two routes for installing software in FreeBSD: Ports and Packages. We have already mentioned Ports a number of times throughout the Guide. This is (generally) our preferred method of installing software in FreeBSD, as many Ports tend to be more up-to-date than their counterparts in the Package Repository. Moreover, we believe that there is a certain advantage in compiling software from source--namely, the myriad of options you can set (for many Ports) at compile time.

Ports
Packages

Installing software through Ports

First things first. Make sure your Ports tree is up-to-date. We recommend updating your Ports tree at least once a month. This will ensure that you see a current list of software available through Ports (and will prevent you from getting error messages about files not being available because you're trying to download an outdated version that no longer exists on the remote server). As root,

cvsup /root/ports-supfile

If you don't know what this means or don't have a ports-supfile set up, read this for some basic setup instructions.

The actual installation procedure for software found in Ports is simple and straightforward. If, for example, we wanted to install Mplayer, we would issue the following commands:

cd /usr/ports/multimedia/mplayer
make install clean

That's it. Wait a little while, and you should have a nice fresh install of the desired application.

One thing to note is that every so often you will want to empty the contents of your /usr/ports/distfiles directory. When you install an application through Ports, the source to the app is first downloaded to your computer from the remote server. Once the application has been installed, however, there is little need to keep the archives containing the source.

cd /usr/ports/distfiles
ls

The reason why you should 'ls' is to make sure you're in the correct directory. Erasing the contents of the wrong directory could be very bad. Depending on how many Ports you've installed since the last time you cleaned out your /usr/ports/distfiles directory, your 'ls' should return something like this:

fongsaiyuk# cd /usr/ports/distfiles/
fongsaiyuk# ls
K12-1.bdf.gz                        kanji18
K12-2.bdf.gz                        kanji26
K14-1.bdf.gz                        knj10-1.1.tar.gz
K14-2.bdf.gz                        lame-3.96.1.tar.gz
Kappa20-0.396.tar.bz2               lcms-1.14.tar.gz
MPlayer-1.0pre7.tar.bz2             leafpad-0.8.1.tar.gz
Mesa-6.2.1-20050213.tar.bz2         libao-0.8.5.tar.gz
XML-Parser-2.34.tar.gz              libcroco-0.6.0.tar.bz2
aalib-1.4rc5.tar.gz                 libexif-0.6.12.tar.gz
anthy                               libgcrypt-1.2.1.tar.gz
aspell-0.60.2.tar.gz                libgpg-error-1.0.tar.gz
aspell6-en-6.0-0.tar.bz2            libiconv-1.9.2.tar.gz
aterm-0.4.2.tar.gz                  libmng-1.0.8.tar.gz
audiofile-0.2.6.tar.gz              libotf-0.9.3.tar.gz

Notice that there are a few directories (the names without extensions) as well. We can issue a single command to clean up this mess:

rm -r *

There. Do another 'ls' and you should get nothing in response. Your /usr/ports/distfiles directory has been cleaned up.

What if we want to customize our install of Mplayer (or any other Port)? No problem. To find the various compiling options available for Mplayer, simply open the Makefile in a text editor.

vi /usr/ports/multimedia/mplayer/Makefile

This will give us an idea of the options available at compile time:

# New ports collection makefile for:      mplayer
# Date created:       10 August 2001
# Whom:               Thomas E. Zander
#                     with lots of help from Vladimir Kushnir
# $FreeBSD: ports/multimedia/mplayer/Makefile,v 1.117 2005/05/17 18:01:39 pav Exp $
#
# There are many knobs to tune mplayer towards your specific wishes
# and preferences.
# You can activate a knob by typing something like
# "make -DKNOB" or "make KNOB=yes" instead of just "make"
#
# A description of the several possibilities is available here:
#
# Core funcionality:
#
# MPLAYER_GENERIC_BUILD
# default: undefined
# By default, the mplayer port creates a custom build based on personal
# preferences.
# If you want to build a generic package with certain fixed options,
# suitable for any CPU within ${ARCH}, define this knob.
# Note: The following knobs will have no effect in this case!
#
# WITH_OPTIMIZED_CFLAGS
# default: undefined
# define if you want to enable -O3 -ffast-math -fomit-frame-pointer
# on gcc build commands. This will improve speed on most machines.
#
# WITHOUT_RUNTIME_CPUDETECTION
# default: undefined
# by default, mplayer is built with support for changing the used cpu
# instruction set while playing. This is necessary for package building.
# If you want to compile a specific version of mplayer working faster
# but only on your cpu type, then define this knob.
# If you define this, there are several additional knobs to explicitly
# disable some possible CPU features. See below.
#
# WITH_NVIDIA
# default: disabled
# Enable nvidia XVMC support for nvidia video cards
# Note: This is highly experimental at the moment and works only for
#       MPEG1/2 using -vo xvmc -vc ffmpeg12mc on FreeBSD-5
#
# WITHOUT_MENCODER
# default: undefined
# the default is to build mplayer with mencoder. If you're sure that you
# don't want to encode or recode any media file, then define this.
#
# WITHOUT_X11
# default: undefined
# the default is to build mplayer with X11 support because of its capabilities
# as a video player. If you don't want to install any X11 environment and use
# mplayer as a multi-format audio-only player, this one is for you.
#
# WITH_GTK1|WITH_GTK2
# default: autodetect GTK1
# if you want mplayer to have gui abilities, you can use this knob to define
# which graphical toolkit set mplayer is built with.
# It defaults to detect and use GTK1 if it finds a working installation on the
# system. This can be overridden by choosing WITH_GTK2 or disable graphical
# user interface by defining WITHOUT_GUI
# Note: If you define WITH_GTK* *and* WITHOUT_GUI, mplayer will be built without
#       gui capabilities.
#       At the moment there is no current gtk2 patch available, so defining this
#       knob has no effect right now.
#
# WITHOUT_GUI
# default: undefined
# normally mplayer comes with gmplayer if gtk is installed on the system.
# If you want to force mplayer to disable the graphical user interface and
# build without gui ability, define this.

(Note: the Makefile in its entirety contains far more options and is much bigger than this, but these are a few sample "knobs" to give you an idea of the options available for us to define).

First of all, note that on Line 10 of the Makefile, the maintainer of this Port has been kind enough to tell us how to set any of these options at compile time: type "make KNOB=yes". In other words, if we wanted to build Mplayer without a GUI ("WITHOUT_GUI"), instead of issuing the default "make install clean" command, we would issue:

make WITHOUT_GUI=yes install clean

This will compile Mplayer without a GUI, an option that both Dan and I (Kevin) have found useful. You can set multiple options as well. For example, if you wanted to build Mplayer without a GUI and you wanted to build it in German, you would issue:

make WITHOUT_GUI=yes WITH_LANG=de install clean

Set as many options as you like in this fashion.

It is also possible to set compiling options by editing the Makefile itself. For example, if you wanted to install CUPS, we normally recommend setting three options at compile time. These can be set using the above-noted method for setting options for Mplayer, but can also be set by adding lines to the end of the Makefile itself:

vi /usr/ports/print/cups/Makefile

This will bring up a very concise file that (unfortunately) does not give us a nice list of compile options:

# ex:ts=8 -*-mode: makefile-*-
#
# New ports collection makefile for:    cups
# Date created:        2003-01-22
# Whom:                Alan Eldridge
#
# $FreeBSD: ports/print/cups/Makefile,v 1.23 2005/01/24 17:22:59 sem Exp $
#
 
PORTNAME=      cups
PORTVERSION=   ${CUPS_PORTVER}
PORTREVISION=  ${CUPS_PORTREV}
PORTEPOCH=     ${CUPS_PORTEPOCH}
CATEGORIES=    print
MASTER_SITES=  # empty
DISTFILES=     # empty
EXTRACT_ONLY=  # empty
 
MAINTAINER=    asa@agava.com
COMMENT=       The Common UNIX Printing System: Metaport to install complete system
 
LIB_DEPENDS+=  cups.2:${PORTSDIR}/print/cups-base
RUN_DEPENDS+=  espgs:${PORTSDIR}/print/cups-pstoraster \
               ${LOCALBASE}/sbin/cupsaddsmb:${PORTSDIR}/print/cups-lpr
 
.if make(package)
DEPENDS_TARGET="package"
.endif # make(package)
 
USE_PERL5=      yes
NO_BUILD=       true
 
do-patch:
       ${DO_NADA}
 
do-install:
       ${DO_NADA}
 
.include "${.CURDIR}/../../print/cups/Makefile.common"
.include
.include

Not much to look at, right? Okay, so if we were following our FreeBSD Guide instructions on Printing with CUPS, we would want to add the following 3 lines to the end of the Makefile:

CUPS_OVERWRITE_BASE=yes
NO_LPR=yes
WITH_CUPS=yes

Save changes and exit with 'ZZ', then issue our default "make install clean" instruction to compile CUPS with the 3 options we added directly to the Makefile.

But what if we wanted the same 3 options to remain set when we upgrade CUPS? No problem. Instead of (or in addition to) setting these 3 options directly in the CUPS Makefile, we can make them apply to future versions of CUPS by adding them to /etc/make.conf:

vi /etc/make.conf

This will display any compile options you set that will apply whenever applicable (i.e. any time you install a Port that recognizes them as valid options):

# added by use.perl 2005-05-20 08:38:14
PERL_VER=5.8.6
PERL_VERSION=5.8.6
COMPAT4X=true
CUPS_OVERWRITE_BASE=yes
NO_LPR=yes
WITH_CUPS=yes

See those last 3 lines? Unlike the CUPS Makefile, which will be overwritten the next time I upgrade my Ports tree, the options set in /etc/make.conf will stay there until I delete them.

Installing software through Packages

While installing software through Packages does not allow us to customize our install the way installing from Ports does, Packages nevertheless have their uses. For starters, installing a piece of software through Packages takes a small fraction of the time it takes to install through Ports. That is because whereas when you install through Ports, your system has to compile the application from source, installing through Packages extracts and registers precompiled binaries on your system.

Sound nice? Amongst other things, one major annoyance with Packages is that they tend to be outdated compared with their counterparts in Ports. Moreover, Packages can provide some major headaches when they were built on another system with different versions of libs that you have on your system or with options set that you don't want. Just try installing a 4.x Package in 5.x and see what I mean.

That said, there may still be times when you wish to install a piece of software from its binary Package rather than through Ports. OpenOffice.org is a magnificent example of this. Installing this piece of software through Ports requires approximately 4 GB of hard disk space (for all of the temporary files used during the compiling process) and an overnight wait even on pretty decent hardware. By contrast, it takes only a few minutes to install this same application by binary Package.

Installing an application through Packages is pretty straightforward. If, for example, we wanted to install Gaim through Packages, as root type:

pkg_add -r gaim

This will download the most recent version of Gaim available as a binary package, and in a short process install it on your system.

Sometimes (due to the nuances of indexing on the server) this command will fail to retrieve a Package. If that is the case, or for any other reason, we can manually download a Package before attempting to install it. While this can also be done with a web browser, I like command-line tools so we're going to download this from the command line:

ftp -a ftp2.freebsd.org

You should be greeted with a message like this:

reinholz@fongsaiyuk$ ftp -a ftp2.freebsd.org
Connected to ftp2.us.freebsd.org.
220 ftp2.us.freebsd.org FTP server (Version 6.00LS) ready.
331 Guest login ok, send your email address as password.
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

At the ftp> prompt, we can issue commands to navigate our way around the server. This can be done very similarly to browsing your local system:

cd pub/FreeBSD/ports/packages/
ls

This will look a lot like the directory structure of our local /usr/ports directory. Navigation is pretty similar. For Gaim:

cd net
ls

This will look a little bit different from what you're used to in Ports. Rather than a list of directories corresponding to available applications, this will generate a long list of packages, usually in *.tbz format. (Tar archives compressed using bzip). As of the writing of this page (5 June 2005), the package for Gaim listed on the server was "gaim-1.3.0_1.tbz"

To download this package, type:

get gaim-1.3.0_1.tbz

This will retrieve the package and download it to our current directory (your Home directory if you just opened a new terminal window).

ftp> get gaim-1.3.0_1.tbz
local: gaim-1.3.0_1.tbz remote: gaim-1.3.0_1.tbz
229 Entering Extended Passive Mode (|||61317|)
150 Opening BINARY mode data connection for 'gaim-1.3.0_1.tbz' (5085357 bytes).
26% |*********                            | 1340 KB  191.44 KB/s    00:18 ETA

Nice, huh? You even get a slick little download status indicator. Wouldn't it be great if cp gave you something like this?

Once your download has finished, disconnect from the server:

exit

A successful download and exit should look like this:

ftp> get gaim-1.3.0_1.tbz
local: gaim-1.3.0_1.tbz remote: gaim-1.3.0_1.tbz
229 Entering Extended Passive Mode (|||61317|)
150 Opening BINARY mode data connection for 'gaim-1.3.0_1.tbz' (5085357 bytes).
100% |*************************************|  4966 KB  236.80 KB/s 00:00 ETA
226 Transfer complete.
5085357 bytes received in 00:20 (236.80 KB/s)
ftp> exit
221 Goodbye.
reinholz@fongsaiyuk$

To install this package, make sure you're in the download directory (do a quick 'ls' to double-check if you're not sure), and as root:

pkg_add gaim-1.3.0_1.tbz

That should install the package, after which time you can delete the .tbz file we downloaded.

What if the Package refuses to install, complaining about one or more missing dependencies? While not necessarily recommended (because you'll probably have additional headaches trying to get the app to run post-install), to override error messages and install the Package anyway, type:

pkg_add -f gaim-1.3.0_1.tbz

NOTE that the "-f" flag can also be set in the case of a remote Package. Simply combine it with the "-r" flag:

pkg_add -rf gaim

Again, generally it is not a great idea to force an installation using the "-f" flag, but at times it can be very useful. Sometimes the Package wants old versions of dependencies that you already have installed on your system. Forcing the installation to proceed anyway can yield satisfactory results, if the application recognizes and uses the newer versions of its dependencies already installed on your system.

Creating binary packages of installed software

Sometimes, you might want to create a binary package of an application you have installed on your system. For example, if you compiled OpenOffice.org with some custom options, such as USE_GNOME or WITHOUT_JAVA, and you want to back it up, you want to install it on your other three FreeBSD systems without spending the time compiling it on each computer, or you want to give it to a friend, creating a binary package is a simple way to redistribute the application in quick-to-install binary form with your custom options.

First, we have to find the full name of the installed application, i.e. name with version number.

pkg_info -a | grep openoffice

Which returns:

en-US-openoffice.org-2.0.0

So, to create a binary package of this application,

pkg_create -b en-US-openoffice.org-2.0.0

A minute or two later, you should see the following file in the current directory: "en-US-openoffice.org-2.0.0.tgz". Anyone you give this file to can then install it simply by typing:

pkg_add en-US-openoffice.org-2.0.0.tgz

Make sure, of course, to specify the full path to the file, if you do not execute the "pkg_add" command from the same directory where the file is located. Also note that dependencies of the package will not be automatically downloaded, since we're installing the package from a local file. Any dependencies that cause the install to fail will need to be installed from Ports or Packages before the package we created will successfully install on another system.

If you have the package's dependencies already installed, but it is complaining because you have different versions of these dependencies than those required by the package installed, you can probably run the following command relatively safely:

pkg_add -f en-US-openoffice.org-2.0.0.tgz

Which will force the package to install even though not all of its requisite dependencies are present on the target system.

As of FreeBSD 6.0-RELEASE, it is also possible to create packages of the installed application's dependencies at the same time you create a package of the installed application. This might make installing the package on another system easier (good idea to create a new directory and run this command within it):

pkg_create -Rb en-US-openoffice.org-2.0.0

After a few minutes, you should have packages of OpenOffice.org and a bunch of its dependencies in the current directory. Doing an "ls" will reveal an impressive list, along the order of this:

ORBit2-2.12.4_1.tgz                     jpeg-6b_3.tgz
atk-1.10.3.tgz                          libIDL-0.8.6_1.tgz
bitstream-vera-1.10_2.tgz               libXft-2.1.7.tgz
cairo-1.0.2_1.tgz                       libbonobo-2.10.1_2.tgz
cdparanoia-3.9.8_7.tgz                  libiconv-1.9.2_1.tgz
en-US-openoffice.org-2.0.0.tgz          libxml2-2.6.22.tgz
expat-1.95.8_3.tgz                      linc-1.0.3_4.tgz
fam-2.6.9_6.tgz                         openldap-client-2.2.29.tgz
fontconfig-2.3.2,1.tgz                  pango-1.10.1.tgz
freetype2-2.1.10_1.tgz                  perl-5.8.7.tgz
gconf2-2.12.1.tgz                       pkgconfig-0.20.tgz
gettext-0.14.5.tgz                      png-1.2.8_2.tgz
glib-2.8.4.tgz                          popt-1.7.tgz
gnomehier-2.0_7.tgz                     samba-libsmbclient-3.0.20b_2.tgz
gnomemimedata-2.4.2.tgz                 shared-mime-info-0.16_2.tgz
gnomevfs2-2.12.2.tgz                    tiff-3.7.4.tgz
gtk-2.8.8.tgz                           xorg-fonts-encodings-6.8.2.tgz
hicolor-icon-theme-0.5.tgz              xorg-fonts-truetype-6.8.2.tgz
howl-1.0.0.tgz                          xorg-libraries-6.8.2.tgz

That's a lot of packages! Place these in the same directory on the target system, and "pkg_add en-US-openoffice.org-2.0.0.tgz" as you did with the previously created package. This time, all of the application's dependencies are present locally, so they should be added as well.

Finding/listing installed software in FreeBSD

So you want to know what software you have installed on your FreeBSD system, or you want to check if you have a particular piece of software installed? This is a pretty simple task.

To list all software packages (this includes those installed through Ports and those installed through Packages) installed on your system, issue the following command:

pkg_info -a

This will produce a very long list of applications/utilities and information about them.

To check to see if you have a particular app installed on your system, we can search the package database, including all or part of the application name in the search. If we wanted to check to see if we had OpenOffice.org installed, for example, we could try:

pkg_info -a | grep openoffice

Which on my system returns "en-US-openoffice.org-2.0.0" 37 times. Searching in this fashion often returns multiple results of the exact same thing. Not to worry. It's only installed once.

What if you wanted to broaden your search a little? Try this:

pkg_info -a | grep office

Same result on my system. What if you want to broaden your search even further?

pkg_info -a | grep open

On my system that returns "en-US-openoffice.org-2.0.0", "open-motif-2.2.3_2", as well as a number of descriptions from other packages that contain the word "open".

Get the idea? Use this tool wisely.

Removing software in FreeBSD

There are 2 basic ways to uninstall applications in FreeBSD. The first is to use the "make deinstall" command. To do this, cd to the Ports directory of that application. For example, if we wanted to uninstall bash:

cd /usr/ports/shells/bash
make deinstall

This will remove the application from your system. Note that this method will work even if you originally installed the application through Packages rather than Ports.

The FreeBSD Handbook claims that "make deinstall" will not work if you installed an application through Ports with the "make install clean" command. It claims that it will only work if you installed the application using the "make install" command (which leaves a bunch of temp files on your system from the compiling process, yuck). Not to worry. That information appears to be outdated, as "make deinstall" works just fine at removing an application installed either through Ports or through Packages, whether you did a "make install clean" or not.

The other method of uninstalling an application is using the "pkg_delete" command. This method also works regardless of whether you installed the application through Ports or Packages, and whether or not you did a "make install clean" when you installed through Ports.

The caveat with this command is that you have to know the full name of your application. Normally you would just know the short name, for example, "firefox". That is the command you would enter in a terminal window (or set in your Fluxbox menu) in order to run the application Firefox. However, in order to uninstall, we need to know full name, including version number. To find this:

pkg_info -a | grep firefox

This may generate a list of the same name repeated many times, but that is not important. What is important is that we learn the full name:

firefox-1.0.4,1

That's the full name of Firefox as installed on my system on 5 June 2005. To uninstall this application, as root type:

pkg_delete firefox-1.0.4,1

This will remove Firefox from your system.

Upgrading software in FreeBSD

This is a very simple task that sometimes leads to big headaches and lengthy troubleshooting. In a perfect world in which all goes well, however, there are really only 3 things you should have to do in order to upgrade an application to its newest available version.

Before we do that, however, please note that this section assumes you have portupgrade installed on your system. To find out whether you have it or not, type

pkg_info -a | grep portupgrade

Which should spit out "portupgrade" with a version number. If you get nothing in response, you need to install portupgrade:

cd /usr/ports/sysutils/portupgrade
make install clean

Now that we have portupgrade, we can continue with this section.

First, make sure that your Ports tree is up-to-date. As root:

cvsup /root/ports-supfile

This will update your Ports tree. Once this has finished,

pkgdb -F

This will fix any inconsistencies in your package database.

portupgrade firefox

This will upgrade Firefox to the newest available version in Ports. If you're feeling really lucky, on the other hand, and want to upgrade all of your applications at once (not really recommended but we've all done it from time-to-time out of laziness), type:

portupgrade -a

This will (if successful) upgrade all of your installed applications to the most current versions available in Ports. If unsuccessful, it will stop somewhere in the middle, with some of your packages upgraded, and others unsuccessful because a stubborn application in the middle of the list didn't want to build properly. If this happens, you can always try a "pkgdb -F" and try the "portupgrade -a" again, or more likely you will have to do some searching on Google or your favorite forums. NOTE: it is far more successful to paste all or a portion of the error message that appears in your terminal into Firefox and search for those exact terms than to type some generic search term like "gaim won't build" or "portupgrade fails". The latter 2 won't return any useful results, but your exact error message very well may.

Another useful way to upgrade is to first run the following command:

pkg_version -L =

Which will tell you which of your installed packages are out-of-date. Then, you can run portupgrade on those outdated packages that you want to update. (You might not want to upgrade all of them). The output of this command will look something like this:

reinholz@fongsaiyuk$ pkg_version -L =
expat                               <
openoffice                          <
pkgconfig                           <
png                                 <
xorg-server                         <
xterm                               <
reinholz@fongsaiyuk$

Which tells me that expat, openoffice, and the other listed packages have more recent versions available (and listed) in my Ports tree. (In other words, that these packages are out-of-date). However, I know that I DO NOT want to "upgrade" openoffice. I don't have the patience to wait as this massive app is compiled/installed from source.

So what if you're lazy and want to be able to do a "portupgrade -a", but you don't want certain packages (like openoffice or linuxpluginwrapper) to be included in the upgrade? No problem. All we have to do is edit this file:

vi /usr/local/etc/pkgtools.conf

And add the following lines if they do not already exist:

  HOLD_PKGS = [
    'bsdpan-*',
    'linuxpluginwrapper*',
    'en-US-openoffice*',
  ]

Which tells portupgrade not to upgrade these packages. Very useful tool.

One final note: it is recommended that you check "/usr/ports/UPDATING" for important information before attempting a portupgrade. It is also a good idea to check FreshPorts for any critical information before upgrading. For example, there is an issue with upgrading any of your Gnome components (any of the gnomelibs, gnomevfs, gtk2, etc). Chances are you have at least some of them installed. We have a special page here dealing with that particular issue.

Granted, that's in a perfect world, and most people don't have the time (or are too lazy) to check these valuable resources. (I'm oftentimes one of them). Do so at your own risk, but know that you'll hardly be alone if you take this sometimes dangerous shortcut. As long as you back up your data periodically and you're not a system admin, you'll probably be okay.