To build different projects, we may need to install different versions of the same software. To use a specific version, we may need to create a sym link to that version of the executable.

On Ubuntu, we can also alleviate the issue of switching command versions with update-alternatives.

One of the most common tool that needs multiple versions is GCC. On Ubuntu 18.04, the default GCC version is 7.4.0. However, sometimes, we also need to use older GCC such as gcc-4.8. The GCC toolset will install several executables under /usr/bin/, such as gcc-4.8, g++-4.8, among others.

If we want the command gcc to point to /usr/bin/gcc-4.8, we often want g++ to point to /usr/bin/g++-4.8. Using symlinks to manage version switch is not convenient in this case, since we need to create two or more symlinks. If we want to switch back to GCC 7.4, we then need to remove the old symlinks and create new ones, which is cumbersome.

update-alternatives provides what is called master and slave alternatives, where if you change the master symlink, the slave symlinks will also get changed automatically. The syntax is:

update-alternatives --install link name path priority [--slave link name path]

link is the generic name used to invoke a command, for example, /usr/bin/gcc. name is the alternative name used under the alternative directory (which is usually /etc/alternatives), for example, gcc. path is the actual path to a specific version, e.g., /usr/bin/gcc-4.8. priority is a score given to this alternative. If you have several alternatives for a command, the one with the highest priority will be used. The link after --install is the master link.

The format for --slave is the same as master link. You are allowed to add multiple slave links like this:

update-alternatives --install link name path priority --slave link1 name1 path1 --slave link2 name2 path2

For GCC, we can use the following command to add two alternatives:

update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 10 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 20 --slave /usr/bin/g++ g++ /usr/bin/g++-7

So by default, GCC 7.4 will be used. In order to switch to another versions, we can run the following command:

update-alternatives --config gcc

You will be prompted to choose an alternative from a list of alternatives. After that, the gcc and g++ version will be switched to the version you want.

The alternatives work like this. /usr/bin/gcc will point to /etc/alternatives/gcc, which in turn points to the real command /usr/bin/gcc-7 or /usr/bin/gcc-4.8 depending on which alternative you choose. So when you change the alternative, you are changing the mapping from /etc/alternatives/gcc to the actual executables.