Stow Version Manager
Published on
Updated on
Suppose you need a newer or specific version of a package that isn’t included in your standard linux repo. The standard procedure is to do something like the following…
git clone https://github.com/brandon-rozek/project.git
cd project
./configure
make
sudo make install
Depending on how the package is configured, it will put the executable, configurations, and libraries in /usr/local/
or other places in your system.
The difficulty comes, when it is time to change versions of the software. Some people include a nice make uninstall
target which can help you track down which files were installed. Other software packages aren’t so convinient. This is where stow comes in. It allows you to easily change between software versions.
How does this work? First let’s create a stow directory in /usr/local
sudo mkdir /usr/local/stow
Then let’s go to the project we want to install and add a flag to configure to tell it where to install
git clone https://github.com/brandon-rozek/project.git
cd project
./configure --prefix=/usr/local/stow/project-v1
make
sudo make install
For cmake based projects…
git clone https://github.com/brandon-rozek/cmake-project.git
cd cmake-project
mkdir build
cd build
cmake3 -DCMAKE_INSTALL_PREFIX=/usr/local/stow/cmake-project-v1 ..
make
sudo make install
Now let’s check out the installation directroy
cd /usr/local/stow/project-v1
ls
etc
lib
bin
You’ll notice here that we’ll have the same setup as /usr/local/etc/
, /usr/local/lib/
and /usr/local/bin
. That’s because when we run stow
it’ll go through and create the appropriate symlinks to the files.
cd /usr/local/stow
sudo stow project-v1
Stow Flags
Stow will go into the folder and then create the appropriate symlinks relative to the parent directory of stow, which in this case is /usr/local
. If you don’t want it to create the symlinks in the parent directory then you can set the target somewhere else with --target
or -t
.
cd /home/brandon/stow
sudo stow --target /usr/local project-v1
If you don’t want to cd
into your stow directory, you can set --dir
or -d
to indicate where that is.
sudo stow --dir /home/brandon/stow --target /usr/local project-v1
Summary of Flags (From the Man page)
Flag | Description |
---|---|
--no |
Do not perform any operations that modify the filesystem; merely show what would happen. |
--dir=DIR |
Set the stow directory to “DIR” instead of the current directory. This also has the effect of making the default target directory be the parent of “DIR”. |
--target=DIR |
Set the target directory to “DIR” instead of the parent of the stow directory. |
--stow |
Stow the packages that follow this option into the target directory. This is the default action and so can be omitted if you are only stowing packages rather than performing a mixture of stow/delete/restow actions. |
--delete |
Unstow the packages that follow this option from the target directory rather than installing them. |
--restow |
Restow packages (first unstow, then stow again). |
--no-folding |
Disable folding of newly stowed directories when stowing, and refolding of newly foldable directories when unstowing. |
Applications
Switching between versions
This makes changing versions of software really easy.
cd /usr/local/stow
sudo stow -D project-v1
sudo stow project-v2
And like that you’ve switched versions from 1 to 2!
Managing dot files
This is also a great way to store dot files for your user directory. Here is an example of what I do:
/home/brandon/stow
├── bash
│ └── .bashrc
├── git
│ └── .gitconfig
└── tmux
└── .tmux.conf
Troubleshooting
If you get a command not found for an executable you know lives in /usr/local/bin
then it might be because your PATH
isn’t setup to look there.
Inside your ~/.bash_rc
export PATH=$PATH:/usr/local/bin