In my previous article about Fink, I covered how to install Fink and some basic things you can do with this package management system. In this article, I'll tackle some more advanced Fink topics, like building binary packages, running your own binary distribution server, and creating Fink packages for your own software.
Last time I explained how you can install software from source with the fink install command. Let's see what happens when you execute that command. Suppose you want to install the GNU Prolog compiler:
fink install gprolog
It doesn't matter if you use the graphical user interface FinkCommander, because it uses the same fink command.
What's happening now? Fink downloads the source tarball, generally a tar.gz or a tar.bz2 file. Then it decompresses the file and unpacks the tar archive. If the source code comes with a patch in order to get the software working on Mac OS X, the patch gets applied. Then the software gets compiled: the configure script generates a makefile and the command make uses this makefile to execute the right steps to compile the program.
Once the software has been compiled, Fink installs the software in a temporary directory. Then it creates a binary package file with extension deb: that's gprolog_1.2.16-1_darwin-powerpc.deb in our example. This gets installed in the directory /sw/fink/debs. What has happened until now is the build phase: Fink has built the package. The deb package contains the whole directory structure which has to be installed. Now Fink calls the dpkg tool to install the package.
The build and install phases are in fact two separate steps. This means you can build a package without installing it or, even more interesting, you can build a package and install it on another Mac. This computer doesn't need to have Fink or the Developer Tools installed. A deb file contains all needed files, including the binary program. You can distribute it to another Mac and install it there, as long as this computer has the libraries and other programs the program uses. These libraries can also be installed from a deb file.
When you want to build irssi for example without installing it, all you have to type in Terminal.app is this:
fink build irssi
In FinkCommander, we can do the same by selecting the package irssi in the list and choosing the menu item Source -> Build.
One caveat: dependencies, packages needed by the built package, are installed, not just built.
To distribute the deb file to another computer, move it to the directory /sw/fink/debs and execute fink install gprolog. Fink finds the binary package file and installs the GNU Prolog compiler from it.
In the last article you saw that not all Fink packages are available as a binary package. If you want to distribute a certain set of binary packages to a group of clients, you can place binary packages of all the programs you use in your organization on a central server, the distribution server. The clients can download the packages from the server and install them then. This approach has several advantages:
Let's see how we can set up such a configuration. On the distribution server, you have to take the following steps:
fink build command (or FinkCommander's equivalent). You don't have to install these packages on the server.fink scanpackages to update the list of available binary packages.The first three steps are straightforward. For the fourth step, you actually have some choices. You can make the directory available through different methods: via HTTP, FTP or SSH. We will show how to do it via HTTP, because it's rather easy.
You have to change the configuration file of the Apache web server, which is included in Mac OS X. You can't do it with TextEdit or another graphical editor, so you have to use the command-line editor vim. Type the following in Terminal.app:
sudo vim /etc/httpd/httpd.conf
Give your password when asked. Scroll to the following line:
<IfModule mod_alias.c>
Then type i for going into insert mode and add the following after the IfModule line:
Alias /fink /sw/fink
<Directory /sw/fink>
Options Indexes FollowSymLinks
</Directory>
You can select and copy it from here. These lines tell the web server to share the contents of the directory /sw/fink on the URL /fink. Afterwards, push the Esc button and type :wq to save the changes and quit vim.
Now start the Apache web server by enabling Personal Web Sharing in the Sharing section of System Preferences. If the web server was already enabled when making the changes to /etc/httpd/httpd.conf, we have to restart the server to read the configuration file again:
sudo /usr/sbin/apachectl graceful
If you don't want to use a web server, you can instead share the Fink directory on an FTP server (included in Mac OS X), or even with SSH (also included in Mac OS X). The details are left out here.
Every time you add new or updated binary packages on the distribution server, you have to run the fink scanpackages command to update the list of available binary packages. Otherwise the clients can't download these new packages.
|
Related Reading Mac OS X Tiger for Unix Geeks |
|
Your central server is ready to distribute binary packages. Now you have to configure the clients to connect to this server. On each client, you have to take the following steps:
fink configure and choose the option to use binary packages. This means typing Y when asked "Should Fink try to download pre-compiled packages from the binary distribution if available? [Y/N]." Alternatively, you could place the line UseBinaryDist: true in the configuration file /sw/etc/fink.conf (remember to open it with sudo vim in Terminal.app).sudo vim /sw/etc/apt/sources.list and add the following lines to the top of the file: deb http://192.168.0.1/fink stable main crypto
deb http://192.168.0.1/fink unstable main crypto
deb http://192.168.0.1/fink local main
If you used FTP or SSH instead of HTTP, the protocol http has to be changed appropiately in these lines.
Now run fink selfupdate. If all goes well, the client discovers the server and you see some lines like this in the output:
Hit http://192.168.0.1 stable/main Packages
Now if you install or update a package on the client with the fink or apt-get command, Fink will first search to see if a binary of the package is available on the distribution server (because the added lines appear first in the file). If available, the package will be downloaded from the server. Otherwise, Fink will search on the local disk and the official binary distribution server. When no binary is found at all, Fink will download the source and compile it. As for the rest, don't forget to update the list of packages regularly with fink selfupdate. Only then will clients discover new packages on the distribution server.
I already mentioned dependencies. Fink actually has a neat command to show you the dependencies of a package: fink show-deps. As an example, you'll want to know on which packages irssi depends:
koan$ fink show-deps irssi
Information about 5134 packages read in 7 seconds.
Package: irssi (0.8.9-25)
To install the compiled package...
The following other packages (and their dependencies) must be installed:
glib2-shlibs
libncurses5-shlibs
ncurses
perl581-core
The following other packages must not be installed:
irssi-ssl
To compile this package from source...
The following packages are also compiled at the same time:
[none]
The following other packages (and their dependencies) must be installed:
fink (>= 0.13.0-1)
glib2-dev
glib2-shlibs
libncurses5
libncurses5-shlibs
ncurses
perl581-core
The following other packages must not be installed:
[none]
As you see, after you type fink show-deps irssi, Fink searches in its packages database for irssi. Then it shows two things: the list of packages you need to install the binary package, and the list of packages you need to compile the package. If you set up a binary distribution server and want to make sure the clients can download binaries of all needed packages from the server, you can search for the dependencies of all the packages you want to distribute and build them on the server. With a little bit of shell scripting knowledge, you can even create a script that generates a list of all needed packages from a list of wanted packages and install them on the server.
You can create a source package for software that Fink doesn't have in its index, e.g. your own software. Let's see how you can do this. I want to create a source package for the gnuvd dictionary program. In its simplest form, it can look like this:
Package: gnuvd
Version: 1.0.2
Revision: 1
Maintainer: Koen Vervloesem <koen.vervloesem@myrealbox.com>
HomePage: http://www.djcbsoftware.nl/code/gnuvd/
License: GPL
Description: Dutch dictionary program that uses the Van Dale(tm) website
# Unpack Phase
Source: http://www.djcbsoftware.nl/code/gnuvd/gnuvd-%v.tar.gz
Source-MD5: 1d2a28c25da8c1cb3cbd1aa60b28864c
# Configure Phase
ConfigureParams: --prefix=%i --mandir=%i/share/man --datadir=%i/share/doc/%n
# Install Phase
DocFiles: AUTHORS COPYING INSTALL README README.nl
The package states general information such as the name, version, description, maintainer, etc. Revision is the version of the Fink package, not the original source. The first time you make a package for a specific program, you make the Revision: 1, and you update it each time you make a new version of the package.
Lines beginning with # are comments. I wrote comments to mark the unpack, configure, and install phases. In the Source line, there's a %v sign. This will be substituted by the version (1.0.2) of the software. If a new version of gnuvd comes out, I only have to change the version in the second line of the package file, if I use %v in all other places in the file. The Source-MD5 number can be computed with the md5 command in Terminal.app. Just download the gnuvd-1.0.2.tar.gz file, go to the directory it's in, and type:
koan$ md5 gnuvd-1.0.2.tar.gz
MD5 (gnuvd-1.0.2.tar.gz) = 1d2a28c25da8c1cb3cbd1aa60b28864c
Copy the value to the package file. Fink uses it to check that the file isn't tampered with or damaged when downloaded.
|
In the line ConfigureParams, you set some parameters so that all files will be installed in the right directory. The --prefix option says that the /sw directory tree should be used. The --mandir and --datadir options are responsible for the right placement of the manpages and the documentation. In the install phase, we have to copy the list of files after DocFiles to the documentation directory. To install gnuvd, Fink has to execute the make install command.
To find for yourself which steps you have to make in the different phases with a specific program, you have to read the INSTALL file. The gnuvd package is a simple example, but Fink packages can be more difficult to make.
Now save this file as gnuvd.info. The first thing we do is validate it with the fink validate command. This will check whether our info file follows the guidelines for Fink packages:
koan$ fink validate gnuvd.info
Warning: Length of package description exceeds 45 characters. (gnuvd.info)
It looks rather OK. You shouldn't get an error, just a warning. The description you wrote in the info file will be displayed by the fink list command, so it should be very short and informative, preferably less than 45 characters. Shorten the description to: "Dutch dictionary using the Van Dale website." That should be clear. fink validate doesn't complain anymore, so the package file seems OK.
The next step is trying to build the package. You copy (as root, so with sudo) the gnuvd.info file to /sw/fink/dists/local/main/finkinfo/ to make it available to Fink. Then you download the file with the source code in /sw/src. Go in Terminal.app to /sw/src and type:
zen:/sw/src koan$ sudo wget http://www.djcbsoftware.nl/code/gnuvd/gnuvd-1.0.2.tar.gz
Password:
--14:03:57-- http://www.djcbsoftware.nl/code/gnuvd/gnuvd-1.0.2.tar.gz
=> `gnuvd-1.0.2.tar.gz'
Resolving www.djcbsoftware.nl... 217.22.64.74
Connecting to www.djcbsoftware.nl|217.22.64.74|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 136,078 (133K) [application/x-tar]
100%[====================================>] 136,078 135.17K/s
14:03:58 (134.79 KB/s) - `gnuvd-1.0.2.tar.gz' saved [136078/136078]
Then:
zen:/sw/src koan$ fink build gnuvd
If all goes fine, you end up with something like this:

Figure 1. We have built the gnuvd package.
Now the directory /sw/fink/dists/local/main/binary-darwin-powerpc/ contains our binary package gnuvd_1.0.2-1_darwin-powerpc.deb. Let's inspect the package contents. This can be done with the command dpkg -c:

Figure 2. The contents of our gnuvd package
This looks OK too: all files will be installed under /sw, as they should be. For a last check, validate the deb file:
zen:/sw/fink/dists/local/main/binary-darwin-powerpc koan$ fink validate gnuvd_1.0.2-1_darwin-powerpc.deb
Validating .deb file gnuvd_1.0.2-1_darwin-powerpc.deb...
If you don't get an error, you should be able to install the binary package:
zen:/sw/fink/dists/local/main/binary-darwin-powerpc koan$ fink install gnuvd
Password:
Information about 5135 packages read in 1 seconds.
The following package will be installed or updated:
gnuvd
/sw/bin/dpkg-lockwait -i /sw/fink/dists/local/main/binary-darwin-powerpc/gnuvd_1.0.2-1_darwin-powerpc.deb
Selecting previously deselected package gnuvd.
(Reading database ... 18964 files and directories currently installed.)
Unpacking gnuvd (from .../gnuvd_1.0.2-1_darwin-powerpc.deb) ...
Setting up gnuvd (1.0.2-1) ...
And now you're able to use the new package:
zen:/sw/fink/dists/local/main/binary-darwin-powerpc koan$ gnuvd inleiding
`in|lei|ding (de ~ (v.))
1 tekst, woorden ter voorbereiding op de eigenlijke tekst of het eigenlijke verhaal => aanloop, introductie, preambule
2 korte voordracht over een bepaald onderwerp
Now you only have to submit the info file to Fink's Package Submission Tracker. A package reviewer will take a look at it and add it to the Fink tree if the package seems usable. Users can install your package then by just typing fink install gnuvd.
This was a very simple package to make. For more difficult cases, I suggest you read the Fink documentation. You can find more complete information on the Fink website, especially the packaging tutorial and the packaging manual.
In this article I've discussed more advanced ways to work with packages. You saw how to build binary packages and how to distribute them with a dedicated server. You saw how to detect dependencies and how to create a new source package. In this way, you can help the Fink community to build an even greater repository of Unix software for Mac OS X.
Koen Vervloesem has a master's degree in computer science and has been freelancing as an IT journalist since 2000, primarily for Dutch IT magazines.
Return to the Mac DevCenter
Copyright © 2009 O'Reilly Media, Inc.