kaashif's blog

Programming, with some mathematics on the side

Using GNU Stow

2013-12-01

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 make 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 stow $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 stow -D $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

Admittedly, 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

Since 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.