Ubuntu Package Management – Effect of Compiling from Source

compilingpackage-managementsoftware installationUbuntu

I use Ubuntu 12.04. Say I have installed package x from the repository (with all its dependencies) at version 1.7 but I need some functionality that is only available in version 1.8, so I download the source tar and compile it:

./configure  
make  
make install
  • Does this overwrite the existing 1.7 binaries?
  • If the existing binaries are overwritten, does the package manager reflect the new version (1.8) and can package x be updated by the package manager in the future?
  • If package y has a dependency of package x 1.8 – will it be satisfied?

I have been trying to find a good source online that explains this. If you have any recommendations, please let me know.

Best Answer

The overwhelming majority of .deb packages, whether or not they are provided by official repositories, install with the prefix /usr.

What that means is that executables intended to be run by the user go in /usr/bin or /usr/sbin (or /usr/games if it's a game), shared libraries go in /usr/lib, platform-independent shared data go in /usr/share, header files go in /usr/include, and source code installed automatically goes in /usr/src.

A small percentage of packages use / as the prefix. For example, the bash package puts the bash executable in /bin, not /usr/bin. This is for packages that provide the bare essentials to run in single-user mode (such as recovery mode) and to start multi-user mode (but remember, that often includes functionality to mount some kinds of network shares...in case /usr is a remote filesystem).

A small percentage of .deb packages, mostly those created with Quickly, create a package-specific folder inside /opt and put all their files there. Other than that, most of the time /opt is the location used by software that is installed from an executable installer that does not use the system's package manager but does not involve compiling from source. (For example, if you install a proprietary program like MATLAB, you'll likely put it in /opt.)

In contrast to all of this, when you download a source archive (or get source code from a revision control system such as Bazaar or git), build it, and install it, it usually installs to the prefix /usr/local (unless you tell it to do otherwise). This means your executables go in /usr/local/bin, /usr/local/lib, or /usr/local/games, your libraries in /usr/local/lib, and so forth.

There are some exceptions to this--some programs, by default, install to the /usr prefix and would thus overwrite installations of the same programs from .deb packages. Typically you can prevent this by running ./configure --prefix=/usr/local instead of ./configure when you build them. I again emphasize that usually this is not necessary.

(It is for this reason that it makes very good sense for you to put source code that you are building and will install for systemwide use in /usr/local/src, which exists for that purpose.)

Assuming the packaged version is installed in /usr and the version you installed from source is in /usr/local:

  • Files from the installed package will not be overwritten.

    Typically the newer version will run when you manually invoke the program from the command-line (assuming /usr/local/bin or wherever the executables are installed is in your PATH environment variable and appears before the corresponding /usr-prefixed directory, such as /usr/bin).

    But there may be some problems with what launchers are created and made accessible through menus or searching. Furthermore, if you have installed more than one version of a library in different places, it can become a bit more complicated to determine which will be used by what software.

    If you're not actually using both versions of the program or library, then often you should remove the one that you're not using, although in limited situations you might want to keep a package installed to satisfy dependencies.

However, if for any reason files are overwritten (for example, if the source code is installed in /usr rather than /usr/local):

  • The package manager will not know anything about how the software it installed was changed. It will think the old version is installed. Bad problems may result. You should avoid this. If you have created this situation, you should uninstall the software you installed from source (usually with sudo make uninstall in the /usr/local/src/program-or-library-name directory), and then uninstall the package or packages that provide the files that were overwritten (as they will not be restored by uninstalling the version installed from source). Then reinstall whatever version you want to have.

As for fulfilling dependencies:

  • If there is a .deb package that depends on the software you installed from source, and requires the version you installed from source (or higher), that package will not successfully install. (Or, to be more precise, you may be able to "install" it but it will not ever be "configured" so you will not be able to use it.) Dependencies are resolved by what versions of packages are installed, not by what software you actually have.

    Similarly, software will at least try to install completely even if you have manually deleted the files provided by packages on which the software being installed depends. (You should not generally try to harness that for any purpose. The package manager operating based on false information is almost always a bad thing.)

Therefore, if you cannot find a package that provides the version of the software you need, you may need to create your own .deb package from the software you've compiled, and install from that package. Then the package manager will know what is going on. Creating a package for your own use, which you don't need to work well on other people's computers, is actually not very hard. (But I feel that may be outside the scope of your question, as it is currently worded.)