In a previous article, we saw how to install and uninstall packages from source within Linux. These packages are usually wrapped up in "tar.gz" files and installing them is a three step process:
While this is easy, it can also be dangerous. Even though I said in the previous article, that we can simply use the "make uninstall" command to remove the package, that's not the whole story. First, many packages simply do not have an uninstall script for you to use! The good ones do, but many developers don't go to all the trouble of creating uninstall capabilities, as it means extra work for them.
The second problem is that you need to keep the source files lying around permanently on your system in case one day you need to remove it. This is just another thing to keep track of and adds to the complexity of installing from source in Linux. In this article, I'm going to show you how to delete packages in Linux that have been installed from source, but don't have an "uninstall" script attached to them. The first is the manual method which can be quite complicated and time consuming. The other is an automated solution that you need to use before you install any software.
Method 1 - Manual Uninstall if you've Already Installed the Software
If you haven't taken any precautions beforehand and already have software installed from source on your system, then removing it can get somewhat complicated. Fortunately, the concept of "installation" in Linux is a bit simpler than that in Windows.
How Package Installation works in Linux:
In Linux, everything is a file. Even the most complicated software deals only with the installation and manipulation of files and nothing else. This is unlike an operating system like Windows which has complicated things like "registry entries" etc. In Windows, you can't uninstall an application merely by deleting the folder into which the files were installed! That would lead very quickly to a messy and disastrous system. In Linux on the other hand, there's no "registry". Only the files. So if you can manage to reverse the creation of every single file copied by the installation script on Linux, you've removed it from your system!
Getting a List of Files Installed by a Linux Package:
So how do we find out which files were installed by a particular Linux package? Unfortunately, the only way to tell is by examining the output of the "make install" command. For this, you need to have the original source code for you to run it again.
As a demonstration, I'm going to install a software package called "singularity" on my Linux distribution. I've already downloaded and unpacked the files. Here's the output of "make install":
Now we need to parse through this output very carefully and search for all commands that create any kind of file or directory in our system. For example, here I've highlighted a "mkdir" command that creates a new directory in "/usr/etc/" called "bash_completion.d". It's best if you write all this down as you're parsing the output. Keep in mind that it's also dangerous to just delete directories created like this because they might have been installed by another program in the past!
For example, I can confirm that the above directories were just created by checking them out:
Since these directories were just created, I can delete them when uninstalling. But you might not have any way to check whether or not they already existed at the time of the first installation. Here's another directory created by "make install":
So we basically just keep going down the path and taking note of all the files, directories and symbolic links created by the script and reverse them to undo the installation. This can obviously take a long, long time for some packages, but there's no other way to go about it.
In short, installing packages from source in Linux is dangerous unless you take some precautions first. On some distributions, you can use a utility called "checkinstall" which essentially creates a ".rpm" or ".deb" file from the source code and allows you to uninstall it using your inbuilt package manager. But checkinstall doesn't seem to be universally available everywhere.
A more elegant solution is "stow".
Method 2: Using Stow to Install and Uninstall Packages from Source
As mentioned earlier, if you've already gone and installed software from source, this isn't going to help you. But if you want a new technique that will allow you to safely install from source without worrying about unremovable files cluttering up your system, then you need to learn about an amazing tool called "stow".
How Stow Works:
A normal software installation from source uses the default "/usr/local" as the base. All the new files and directories are placed inside it - perhaps conflicting with previous versions or other software. It's a jungle. A tool like stow bring some order into the chaos by doing this instead:
- Source files are copied into a separate directory - NOT "/usr/local";
- Stow then creates symbolic links from the above directory into "usr/local";
- The rest of the system sees these are regular files and it looks as if the package is installed as usual.
- To uninstall, stow will just remove the symbolic links pointing to the first directory;
- The rest of the system now thinks the software is uninstalled;
- You can then delete the entire directory created in step 1 with no consequences.
Let's take a look at this with a concrete example. First we install stow using our regular package manager:
Now let's begin the installation of the software. We go to the directory containing the source code. Our first two lines are pretty much the same.
And now for the final "make install" command, we add a prefix that tells Linux to place all the files into a brand new directory instead of the usual "/usr/local:
make install prefix=/usr/local/stow/singularity
Upon execution, all the files will go into this new directory "/usr/local/stow/singularity" as shown here:
The directory can be called anything you want. It's just nice to have a naming convention of one directory per installation. So far, this has only copied files. The software isn't yet "installed" as such, because the rest of the system can't find it in "/usr/local". Now we go one level up so that we have our project in a single directory:
And now we use the following command:
This command will create symbolic links from all the files inside the "singularity" directory into "/usr/local", and the rest of the system will suddenly "see" the package as if it was installed using the regular channels!
You can see in the screenshot above, that the command "singularity" wasn't working before using "stow singularity". And afterwards, it's being recognized as a command. Using a neat sleight of hand, we've managed to encapsulate all the files created by "make install" into a single directory, and yet Linux thinks that the files are spread across multiple directories as required. Genius!
You can see in the screenshot below, that the files installed into "/usr/local" are actually symbolic links to the "/stow/singularity" directory instead:
Uninstalling Software Using Stow:
To remove the software using stow, I simply navigate to the folder containing all the project directories and type:
stow --delete singularity
This removes all the symbolic links, without actually deleting the files in "/stow/singularity". But to the rest of the system, it appears as if the package has vanished without a trace!
It's rather like magic. I'm now free to delete all the files in the files in "singularity" if I want. One of the great things about stow, is that I don't need to keep the original source code packages from which I installed it in the first place. Since I don't need to run "make install" again to see what was installed where, I can safely dispose of the source files!
Using stow is a foolproof way to easily install software from source in Linux without worrying about whether or not it has an uninstall script. Neither do you need to worry about keeping track of the original source files. It's a wonderful utility that every Linux admin should have in their toolkit in case they need to make use of source files in the absence of prepackaged installers.