spill is a program for creating set of symbolic links from one directory hierarchy which point to corresponding filenames in a separate directory hierarchy. It's primary use is to allow packages built from source to be installed in separate directory trees, which are all linked together under a common directory tree (e.g. /usr/local) to reduce the length of the PATH environment variable. An example might be:

% tar xzvf foobar-0.1.tar.gz
% cd foobar-0.1
% ./configure --prefix=/app/foobar/0.1-1
% make
% sudo make install
% sudo spill /app/foobar/0.1-1 /usr/local

You might think this looks over-complicated and be wondering why you can't just do

% cd foobar-0.1
% ./configure --prefix=/usr/local
% make
% sudo make install

since this would avoid the need to create the links at all. Well, suppose you do this for tens or hundreds of packages you compile yourself. Try taking a look at the contents of one of the directories under /usr/local. How on earth do you tell which files were installed by which programs? This is a maintenance nightmare if you need to delete packages you don't need anymore. The extra effort at configure / compile / install time will pay dividends later, as I've found to my cost in the past.

In the example above, the installation directory /app/foobar/0.1 is used. spill always assumes that the final two path components of the prefix are

  1. The name of the program or package (in this case, foobar)
  2. The version of that program or package (in this case, 0.1-1.) You can use any format you like for this path component. By convention, I always use the upstream version number of the package, then a hyphen, then the build number. This allows me to keep several installations active, perhaps with different configure options (e.g. depending on whether the KDE or GNOME version of the GUI is used).

If spill detects that it needs to replace a link in the target directory during installation, it will check whether the link currently points to the corresponding file in a different version of the same program/package. If so, it will do the replacement automatically. If the existing link points to something in a different program/package spill will complain and won't carry out any of the installation. (You have to resolve the conflict by hand in this case then re-run spill.)

spill is similar in idea to several other programs such as stow, depot, relink etc. However spill is written in C, and compiles to a standalone binary, so has no dependence on perl or another interpreter being available. This may be useful when building up a system from almost nothing. Also, spill makes very few assumptions about the destination directory. In particular, it doesn't assume it is solely responsible for managing the contents of that hierarchy. All it cares about is that it can create links to a new package without any conflicts occurring. (If a conflict is detected, it aborts the operation before the filesystem has been modified at all.)

spill is licensed under the GPL.

Suggestions, bug reports, experiences, praise, complaints etc to the author, please. See this page for contact details.


Version 0.8 - 21 December 2009

Available as source from here. The signature file is here.

Release notes:

Richard P. Curnow (2):
      Fix error in path concatenation for processing ignored paths
      Update release script

Version 0.7 - 19 February 2006

Available as source from here

Release notes:

  • -D option to remove the symlinks for a package given just its name and the path to the symlink area.

Git repository

The git repository is here.


spill comes with a manpage, and includes brief usage information in the program itself. This information is shown below to give an idea of the program's options and capabilities.

spill version 0.8 - segregated package install logical linker
Copyright (C) Richard P. Curnow  2003-2006

spill comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; see the GNU General Public License for details.

Printing this help
Syntax : spill -h
  -h,  --help             Show this help message then exit
Showing just the version
Syntax : spill -V
  -V,  --version          Show the program version then exit

Options for package install (default operation)
Syntax : spill [-f] [-n] [-q] [-x]
               [-l <file> | --conflict-list=<file>
               <tool_install_path> [<link_install_path>] [<ignore_path>...]
  -f,  --force            Attempt install even if expected subdirectories (bin,sbin,lib) are missing
  -r,  --retain           Don't clean out links to older version of the same package first
  -n,  --dry_run          Don't do install, just report potential link conflicts
  -q,  --quiet            Be quiet when installing, only show errors
  -x,  --expand           Expand any existing links to directories when needed
  -o,  --override         Override any existing links that conflict with the new package
  -l <conflict_file>
  --conflict-list=<file>  Filename to which conflicting destination paths are written

<tool_install_path>       Directory specified as --prefix when package was built
                          (relative links are created if this is given as a relative path)
<link_install_path>       Base directory where links are created (e.g. /usr) (default is ".")
<ignore_path>...          Space-separated list of relative paths not to be linked

Options for package removal
Syntax : spill -d [-q] <tool_install_path> [<link_install_path>]
  -q,  --quiet            Be quiet, only show errors
<tool_install_path> and <link_install_path> as above.

Syntax : spill -D [-q] <package_name> <link_install_path>
  -q,  --quiet            Be quiet, only show errors
<link_install_path> as above.
<package_name> is the name of package already symlinked.