ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics

Building Binary PC-BSD Packages

by Dru Lavigne
01/05/2006

FreeBSD is starting to make waves in the desktop arena, and not just as the Darwin core of the popular Mac OS X operating system. Several FreeBSD-based desktop projects have emerged in the past few years and have matured to the point where a nontechnical user can easily install a system fully configured for sound, a network, and applications. In addition to ease of use, benefits include no cost, the BSD license, and the stability and security inherent in FreeBSD.

One of these projects is PC-BSD, which provides two additional features that will make it a strong contender in the desktop market. The first is the Online Update Manager, which with a click of the mouse allows a user either to schedule or to manually check for updates to the operating system and installed applications. If necessary updates exist, the system automatically downloads and applies them, making it a trivial task to keep the system patched.

The second feature is a GUI application installer and uninstaller. While advanced users can still use the FreeBSD ports and packages collection, casual users can simply download a PBI (PC-BSD package) from the PBI application directory, double-click on it, and watch as the GUI installer performs its magic.

PBIs have the advantage of being entirely self-contained. That means casual users won't inadvertently overwrite existing libraries or files by installing and uninstalling applications.

This article shows how to create your own PBI, using Digikam as an example of a rather complex package with many library dependencies. While most PBIs will be easier to generate, I want to demonstrate most of the gotchas you may run across when generating your own PBIs.

While casual users won't be making their own PBIs, you don't have to be a programmer to do so. If you have basic Unix skills, are comfortable with the FreeBSD packages collection, and have a meticulous nature, you can easily create your first PBI in the space of an afternoon. This article assumes that you are working on an existing PC-BSD system.

Step 1: Create Your Staging Area

Also, double-check that there is an existing FreeBSD package in the packages/All/ subdirectory at the FreeBSD ftp site for your FreeBSD release.

Note: at the time of this writing, 6.0-RELEASE had just come out, so there weren't that many packages in 6.0-RELEASE/packages/. Check 6.0-RELEASE/packages first, as it will contain the most up-to-date packages; if yours isn't there, use the one in 5.4-RELEASE/packages/.

Next, become the superuser and create a directory for the application in your regular user account's home directory:

% pwd
/home/dru
% su
Password:

# mkdir -p pbi/digikam
# cd pbi/digikam

Step 2: Download the FreeBSD Package and Any Required Libraries

Using the exact name of the package, you can fetch it directly:

# fetch ftp.freebsd.org/pub/FreeBSD/releases/i386/5.4-RELEASE/packages/graphics/digikam-0.7.2.tbz

Next, install the package to make sure you don't have any missing dependencies. If you're lucky, it will just install and you'll get your prompt back. If you instead get error messages, you will have to fetch the missing dependencies:

# pkg_add digikam-0.7.2.tbz
pkg_add: could not find package libltdl-1.5.10 !
pkg_add: could not find package libexif-0.6.10 !
<snip 9 other missing packages>

# fetch ftp.freebsd.org/pub/FreeBSD/releases/i386/5.4-RELEASE/packages/All/libltdl-1.5.10.tbz
# fetch ftp.freebsd.org/pub/FreeBSD/releases/i386/5.4-RELEASE/packages/All/libexif-0.6.10.tbz
<snip 9 other fetches>

Then try to install the package again:

# pkg_add digikam-0.7.2.tbz

Don't worry if you receive warnings indicating that some software has a greater revision number than is required. You can double-check the install was successful with:

# pkg_info | grep digikam
digikam-0.7.2    Photo album manager for KDE with gphoto2 backend
BSD Hacks

Related Reading

BSD Hacks
100 Industrial Tip & Tools
By Dru Lavigne

Step 3: Prepare the Tarball and Install/Uninstall Scripts

Packages are really compressed tarballs, so start by uncompressing them:

# bunzip2 *.tbz

As you untar each package, you can remove the original tarball:

# tar xvf digikam-0.7.2.tbz && rm digikam-0.7.2.tar
# tar xvf libltdl-1.5.10.tbz && rm libltdl-1.5.10.tar
<snip 10 other untars>

Notice that this created several subdirectories, one of which is bin/. The PBI you create will be a compressed snapshot of this bin/ directory. The rest of this article will show you how to put all the required pieces into it.

The first piece will be a new tarball named base_changes.tar, which contains everything except the contents of bin:

# tar cv --exclude bin -f bin/base_changes.tar .

Next, create an install script and set it as executable:

# vi bin/PBI.SetupScript.sh
#!/bin/sh
cd /usr/local/MyPrograms/$1
tar xvjpf base_changes.tar
rm base_changes.tar

# chmod +x bin/PBI.SetupScript.sh

Then create an uninstall script:

# vi bin/PBI.RemoveScript.sh
#!/bin/sh
cd /usr/local/MyPrograms
rm -Rf $1

# chmod +x bin/PBI.RemoveScript.sh

Notice that when the PBI installs, everything it needs (base_changes.tar) untars into /usr/local/MyPrograms/$1, where $1 represents the name of the PBI. Uninstalling the PBI removes that entire directory.

Because you can use these scripts with any PBI, I keep a copy in my pbi/ directory so I don't have to re-create them:

# cp bin/PBI.* ~dru/pbi

Step 4: Copy Libraries

Now it's time to create a lib/ directory in your staging area's bin/ directory:

# pwd
/home/dru/pbi/digikam/bin
# mkdir lib

Unless you have a very simple application, there can be many dozens of libraries that you need to locate and copy into that custom lib/ directory. ldd will give you the names, but you don't want to spend hours copying pathnames when a script will do it in under a second. This script will work every time, so ~user_account/pbi/ is a good place to keep it. (I've put --- at the beginning and end of the script to make it easy to cut and paste.)

# more ~dru/pbi/lib.sh

---

#!/bin/sh

# this script requires you to input the name of an executable 
# which is referred to as $1 in the script

# copy the output of ldd into a file
# ldd gives the paths to required libraries

ldd $1 > $1_lib.sh

# these statements clean up the output of ldd
# and transforms it into a series of "cp path lib" statements

cat $1_lib.sh | cut -d = -f 2 | cut -d '(' -f 1 > $1_tmp1
sed 's/\>/cp/g' $1_tmp1 > $1_tmp2 ; mv $1_tmp2 $1_tmp1
sed 's/$/ lib/g' $1_tmp1 > $1_tmp2 ; mv $1_tmp2 $1_lib.sh

# this transforms the first non-path line
# into a shebang

sed 's/.*\:.*/\#\!\/bin\/sh/'g $1_lib.sh > $1_tmp1 ; mv $1_tmp1 $1_lib.sh

# this makes the resulting file executable

chmod +x $1_lib.sh

echo "Run the script $1_lib.sh to copy the required libraries"

---

When finished, make the script executable:

# chmod +x ~dru/pbi/lib.sh

As this script takes an executable as an argument, find out the names of your package's executables:

# pwd
/home/dru/pbi/digikam/bin
# file * | grep LSB
dcraw:  ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), for 
    FreeBSD 5.3-CURRENT (rev 5), dynamically linked (uses shared libs), 
    stripped
digikam: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), for 
     FreeBSD 5.3-CURRENT (rev 5), dynamically linked (uses shared libs), 
    stripped
<snip 36 other executables)>

This particular package has 38 executables, so you need to run lib.sh that many times. Note that lib.sh makes a script that copies the libraries needed by that executable. As you create each script, run it and then remove it:

# ~dru/pbi/lib.sh dcraw
Run the script dcraw_lib.sh to copy the required libraries
# ./dcraw_lib.sh && rm dcraw_lib.sh

# ~dru/pbi/lib.sh digikam
Run the script dcraw_lib.sh to copy the required libraries
# ./digikam_lib.sh && rm digikam_lib.sh

<snip other 36 iterations>

When you finish, you'll have a populated lib/ directory:

# ls lib | wc
    79   79   1055

Looks like there are 79 libraries.

Next, double-check whether your package has any lib/ subdirectories:

# ls -F ~dru/pbi/digikam/lib | grep "/"
gphoto2/
gphoto2_port/
imlib2/
kde3/

If there are any, create those subdirectories in your bin/lib/ and copy the appropriate library files over:

# pwd
/home/dru/pbi/digikam/bin/lib
# mkdir gphoto2 gphoto2_port imlib2 kde3
# cp -R ~dru/pbi/digikam/lib/gphoto2/* gphoto2
# cp -R ~dru/pbi/digikam/lib/gphoto2_port/* gphoto2_port
# cp -R ~dru/pbi/digikam/lib/imlib2/* imlib2
# cp -R ~dru/pbi/digikam/lib/kde3/* kde3

Step 5: Look for an Icon and Cleanup bin/

Adding an icon to your PBI is nice. Check whether one came with your package:

# grep -w icons ../+CONTENTS
share/apps/digikam/icons/hicolor/32x32/actions/addimagefolder.png
<snip large output>

This package definitely came with many icons, and this is the one I'm looking for:

# cp ../share/icons/crystalsvg/128x128/apps/digikam.png .

If your package doesn't have any icons, choose your favorite from a subdirectory of /usr/local/share/icons/crystalsvg/128x128/ and copy it to bin/.

When you finish, uninstall the package and its dependencies so they won't interfere when you test the PBI:

# pkg_delete -rx digikam

Finally, double-check bin/ to ensure that it contains only the tarball, the install and uninstall scripts, the binaries, and the lib/ directory.

Step 6: Create the PBI

PC-BSD provides a GUI tool, the Package Creator, which turns the contents of your staging area's bin/ directory into a PBI. Simply double-click on the downloaded file to install the Package Creator. By default, it will place an icon on the desktop and an entry into the Programs menu.

Open up the Package Creator and fill in the first screen with your details:

Package Name:        Digikam
Package Version:    -0.7.2
Author:            Gilles Caulier
Website:        http://www.digikam.org/

Note: The FreshPorts description for your application should include the URL to the application's website. The name of the primary author of the application is usually somewhere at the website for the application.

In the next screen, you can keep the default No for Display License unless the PBI requires otherwise.

In the next screen, browse the Package Directory and select your bin directory:

/home/dru/pbi/digikam/bin/

Under Library Support, select Specify Library Directory, click on the Browse button, and double-click on lib/.

In the next screen, click on Default Program Icon and select your PNG.

Click on Add under Package Executables and type in the program name. Click on the Browse button for Program Executable and select the executable. (In my case it was digikam).

Some programs (for example, Ethereal) need superuser access in order to run. Digikam does not, so I didn't select that option. Click on Save, and then on Next when finished.

Some programs require Mime Types, which you can add in the next screen. (Digikam does not.) The program will then create your PBI--it may take a few minutes, depending on the size of the tarball and the number of libraries. It will tell you when it finishes, and it will place the PBI in that user account's home directory. If you like, click on the Save preset button, which will save all the details to a .pbc file. That can save you some typing the next time you create a PBI.

Step 7: Test the PBI

It's important to test that your PBI successfully installs and uninstalls and that the program works with all its features.

I like to move the PBI to the Desktop so I can double-click on it:

# mv ~dru/Digikam-0.7.2-PV.pbi ~dru/Desktop/

Now leave the superuser account so you're acting as a regular user, and double-check that the application is not currently installed:

# exit
% pkg_info | grep digikam
%

Double-click on the PBI and see what happens. It should prompt you for the superuser password; click on Next twice and then on Finish. You should now have an icon for your application on the desktop. Double-click on it to launch the application, and try all its features to make sure they work.

Once you've confirmed that the application works, double-check that your uninstall script works:

Go to Computer -> PC-BSD Settings -> Remove Programs and remove your program. When that finishes, make sure there is no longer a directory for your application in /usr/local/MyPrograms/.

When Things Don't Work

If you get an error when you launch your program, double-check the contents of the subdirectory for your application under /usr/local/MyPrograms/. If you're missing subdirectories or files, check for a typo in your install script that prevented the tarball from untarring. Likewise, if your application directory remains after uninstalling the program, you have a typo in your uninstall script.

If all the files seem to be there, you may have inadvertently missed running lib.sh on one of the executables and therefore have some missing libraries. Review your history, and if you find your error, add the missing libraries, regenerate a PBI, and test again.

Sometimes the application will launch but features will be missing. In the example of Digikam, the initial splash screen was missing, as were most of the menus. That happens when an application shares files with existing applications such as KDE. To find those files, I checked out the package list for Digikam online.

It was the share files I missed. Because I don't want to interfere with existing applications or copy files outside the self-contained application directory, I used symbolic links. I like to add links one at a time at the command line and relaunch the application to see what happens. Once I knew which symbolic links added the missing features, I added them to PBI.SetupScript.sh and regenerated the PBI. In the case of Digikam, the following links added the missing features. (On the command line, replace $1 with the name of the directory, as $1 will work only in the script.)

% ln -s /usr/local/MyPrograms/$1/applications/kde/showfoto.desktop \ 
    /usr/local/share/applications/kde

% ln -s /usr/local/MyPrograms/$1/share/applnk/Graphics/digikam.desktop \
    /usr/local/share/applnk/Graphics

% ln -s /usr/local/MyPrograms/$1/share/apps/digikam/ \ 
    /usr/local/share/apps/digikam

% ln -s /usr/local/MyPrograms/$1/share/icons/hicolor/ \
    /usr/local/share/icons/hicolor

Note: don't forget the trailing / when creating directory symbolic links.

Finally, if your application relies on GTK+ or Pango, follow the directions on the GTK+ and Pango PBI packaging page.

Step 8: Upload the PBI

Once you've tested your PBI, you can submit it for inclusion on the PC-BSD site so other PC-BSD users can use it.

This is a two-step process. Start by posting a message to the PBIs ready for test wiki; make sure your posting includes the required PBI information. If the PBI testers run across any problems with your PBI, they will reply to your posting. Otherwise, they'll let you know when the PBI is approved and added to the pbiDIR website.

Next, upload your PBI to a FTP server. If this is your first PBI, click on the private message button on the PBI team profile. The PBI team will send you the login information you will need to access the ftp server.

Conclusion

If you haven't had a chance to check out PC-BSD for yourself, I highly recommend it as a desktop for both advanced and casual BSD users. If there currently isn't a PBI for your favorite application, set aside an afternoon and see if you can generate one yourself. You'll find it to be a very satisfying, and possibly addictive, experience.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.


Read more FreeBSD Basics columns.

Return to the BSD DevCenter.

Copyright © 2009 O'Reilly Media, Inc.