Switching Finks

One of the open-source projects I contribute to is Fink, a package manager for OS X; if you’ve used apt-get or yum on Linux, it provides a similar facility, allowing you to install, say, GnuPG by running fink install gnupg. It installs things into its own directory tree, rooted at /sw by default, to avoid interfering with things shipped by Apple (/, /usr) or manually installed by the user (/usr/local.) That is, if you have Fink installed, your system will have /sw/bin, /sw/lib, /sw/etc, /sw/share/man, &c.

So that you can run things installed in these nonstandard locations, Fink provides some shell commands in /sw/bin/init.sh which edit environment variables like PATH and MANPATH to include the /sw/* directories. Most Fink users have . /sw/bin/init.sh in their ~/.profile, so these commands will be invoked when their shell starts.

Having my shell automatically pull in Fink at startup doesn’t work for me, though. It’s important to me to have a clean environment available. For instance, when I’m contributing to non-Fink open-source projects, trying to help someone who doesn’t have Fink installed troubleshoot something, or submitting a bug report for a program that interacts with other programs where I have the Fink version installed, but Apple ships a different version with the system.1 (Note that this is only an issue if program A interacts with program B by invoking it as a standalone process without using an absolute path.2)

Also, as a Fink developer, I actually have multiple Fink installations at different paths,3 and I only want one loaded at a time; I don’t want to activate /Volumes/SandBox/fink/dev-sw in an environment where /Volumes/SandBox/fink/sw has already been pulled in!

It’s much easier to pull Fink stuff in later when I need it than to undo the changes that /sw/bin/init.sh makes to my environment. My solution for making it easy to activate a particular Fink installation was to add the following to ~/.bashrc:

  1. if [ -n "$SW" ]
  2. then export CFLAGS="-I$SW/include"
  3. export LDFLAGS="-L$SW/lib"
  4. export CXXFLAGS="$CFLAGS"
  5. export CPPFLAGS="$CXXFLAGS"
  6. export ACLOCAL_FLAGS="-I \"$SW/share/aclocal\""
  7. export PKG_CONFIG_PATH="$SW/lib/pkgconfig"
  8. export PS1="[$SW_DISPNAME \\W@$(hostname -s)]\\\$ "
  9. . "$SW/bin/init.sh"
  10. export PATH=~/bin:"$PATH"
  11. fi

What this does is arranges it so that if I start a new shell with SW and SW_DISPNAME set, it’ll pull in the Fink installation rooted at the directory $SW and put $SW_DISPNAME in my shell prompt so that I can see which environment I’m using. The extra environment variables before . $SW/bin/init.sh set things up so that if I compile things by hand, they’ll find and link against Fink-installed libraries; the PATH setting at the end is because init.sh places the Fink bin directory at the front of the PATH, and I want my personal bin directory to come before it.

I run the following script (saved as ~/bin/finkinit) when I want to pull in Fink:

  1. #!/bin/bash
  2.  
  3. FINK=${1:-main}
  4.  
  5. case "$FINK" in
  6. main)
  7. SW=/Volumes/SandBox/fink/sw
  8. SW_DISPNAME="fink"
  9. ;;
  10. dev)
  11. SW=/Volumes/SandBox/fink/dev-sw
  12. SW_DISPNAME="fink-dev"
  13. ;;
  14. *) echo "Unknown fink install '$FINK'" >&2 ; exit 1
  15. esac
  16.  
  17. export SW SW_DISPNAME
  18. exec /bin/bash

This gives me a subshell with Fink turned on, which I can exit out of when I want to return to a clean environment. If I run it as finkinit, I get my main Fink installation, or I can run finkinit dev to get an alternate Fink.


  1. Yes, this actually happens somewhat frequently. Sometimes Fink has a newer version of a program than the OS (e.g. Subversion 1.4.6 vs. 1.4.4), or sometimes the Fink version has more extensions enabled (I use Fink’s Apache because it lets me use Fink’s PHP, which in turn lets me install PHP’s MySQL extension by doing fink install php5-apache2-ssl-mysql as opposed to compiling it by hand.) 

  2. Unlike Linux, executables on Darwin have the absolute paths to their shared libraries hardcoded in the binary, so a program linked against /usr/lib/libexpat.1.dylib will always use it, even if /sw/lib/libexpat.1.dylib exists. Linux, on the other hand, uses a search path mechanism at runtime to find the libraries, similar to the way the shell figures out which program to invoke when you command it to ls

  3. At the moment, one for my personal use and a clean one for testing packages I maintain in an environment without extra packages installed. This is important for testing that you’ve declared all of the necessary dependencies. 

Tags: ,

One Response to “Switching Finks”

  1. Chad says:

    Nice! I’ve occasionally been tripped up by having fink installed, and fink versions of things, and forgetting that. This is an excellent solution that lets you go about doing what you want to do without requiring a lot of extra work when you want to do it. Good example of frontloading the effort to save a lot of time and energy later. grin

Leave a Reply

Use Markdown, a wiki-like syntax, to write your comment. Basic HTML tags will also work. For source code with syntax hilighting and line numbers, wrap the code in <pre lang="language" lineno="1">...</pre>

Show Markdown help.

Write Markdown text as if you were writing a plain-text email. Some examples:

  • Paragraphs: Blank lines between blocks of text
  • Links: [link text](http://url.example.com/) or [link text][ref]
  • Bold and italic: *Single* and **double** asterisks respectively
  • Lists: List items start with * or 1.
  • Quoting: Like email, quoted lines start with >
The rise of the [hamburger](http://hamburger.example.com/)
as a form of *currency* can be **attributed** to several
aspects of [Akkadian][akad] [civilization][civ].

   [akad]: http://icanhasgilgamesh.example.com/
   [civ]: http://uruk.example.com/

Yes, the most delicious hamburger of all is not brown, but
green. The green of money. Denominations of hamburger
(and current value in USD:)

* 1/4-pounder ($3.79)
* Cuneiform, or "Cuney" ($8.00)

Problems with the currency:

1. Deflation due to hunger
2. Fraud (soy fillers)
3. Hamburgers not invented yet

As Dr. Tabi said:
> Wallets became foetid and repulsive.
> This was quite the boon for the influential
> Guild of Wallet-Washers.

The rise of the hamburger as a form of currency can be attributed to several aspects of Akkadian civilization.

Yes, the most delicious hamburger of all is not brown, but green. The green of money. Denominations of hamburger (and current value in USD:)

  • ¼-pounder ($3.79)
  • Cuneiform, or “Cuney” ($8.00)

Problems with the currency:

  1. Deflation due to hunger
  2. Fraud (soy fillers)
  3. Hamburgers not invented yet

As Dr. Tabi said:

Wallets became foetid and repulsive. This was quite the boon for the influential Guild of Wallet-Washers.

Comments will be sent to the moderation queue.

Subscribe without commenting