Using GNU Stow
stow is a cool little Perl script which basically just creates and deletes symlinks. That sounds pointless, but let me explain with an example. Let’s say you want to install a program using the usual
make install, which probably installs into /usr/local, which means it’s separated from the rest of your system, which is managed with a “real” package manager. Unless you’re using a
system like BSD ports or Gentoo portage, you cannot have packages which are both managed by the package manager and customised according to your needs. In fact, if you need to do any in-depth modification of the source, I’d say you have no other option than using
make, meaning you have a whole mess of files under /usr/local. This wouldn’t be a problem with package managers, since this “mess” of files can be removed by uninstalling the package, which usually has a list of files it installed, ensuring all stray man pages and example configs are purged from your filesystem. If you used
make install, and there is no
deinstall or similar, then you’re out of luck. The only way to remove the programs you just installed is to wade through the mess that is /usr/local and remove the files manually. That’s where
stow comes in.
The idea of
stow is that you compile your programs normally using
make, but install it into a different directory, usually something like /usr/local/stow/$PKGNAME. This means there is an entire directory tree in that directory containing all of the files that would have been installed by that Makefile. You then enter the /usr/local/stow directory and use the command
$PKGNAME, which creates appropriate symlinks in the directory /usr/local to make it seem as if you just installed the package with
make install into /usr/local. At first, this seems completely useless, but it means you have a guaranteed way of deleting that package - tell
stow to delete all the symlinks. You do this by going into /usr/local/stow and typing
$PKGNAME, which removes all of the symlinks in /usr/local. Here is a series of commands someone using
stow might execute.
$ sudo mkdir /usr/local/stow/my_program $ cd /tmp/my_program $ make install DESTDIR=/usr/local/stow/my_program $ cd /usr/local/stow $ stow my_program
This makes it very simple to upgrade packages or keep multiple concurrent versions lying around.
Using Stow for dotfile management
stow is not really that useful on a bog standard GNU/Linux desktop or laptop, since most packages would be compiled with the usual combinations of compile-time features enabled and available in package repos. The behaviour of
stow can be exploited to provide some other uses, however, one of which involves dotfiles.
Let’s say a user named bob wants to check his dotfiles into his favourite version control system and deploy them easily and quickly on other computers. Right now he has a home directory which looks like this:
bob |-- .bash_profile |-- .bashrc |-- .config |-- .mutt | |-- config_1 | |-- config_2 | `-- config_3 |-- .vim | |-- bundle | `-- ftplugin `-- .vimrc
stow works by recreating a tree of symlinks in the directory above where it is invoked, bob can make a directory called "~/dotfiles" or similar, put all of his dotfiles in there, and stow will create symlinks for him in the directory above "~/dotfiles", his home. His ~/dotfiles should look something like this:
bob `-- dotfiles |-- bash | |-- .bash_profile | `-- .bashrc |-- config | `-- .config |-- mutt | `-- .mutt | |-- config_1 | |-- config_2 | `-- config_3 `-- vim |-- .vim | |-- bundle | `-- ftplugin `-- .vimrc
This means that he can deploy his dotfiles by going into the dotfiles directory and executing
stow bash config mutt vim, which creates symlinks in ~/, duplicating the hierarchy he had in place before. Advantages include: being able to selectively deploy configs only for programs you need on that PC, easy integration with Git, Mercurial and the like as the dotfiles directory can be checked into VCS. Stow has certainly avoided me a few headaches, I recommend it for anyone who needs to use multiple machines.