Dealing with multiple compilers

I don’t know you, but when I am compiling a complicated program and everything goes straightforward I feel a mixture of joy and surprise. Let’s face it, compiling can be quite frustrating, and if you need to compile something relatively old, chances are that you will spend hours and hours trying to understand the compiler error messages.

Several such compiler errors, that in many cases can be quite convoluted, tell you that your program requires an older version, so you first need to install it. I am going to assume that you have sudo rights, otherwise, we will be playing the game of compiling a compiler, something that I recommend you to do at least and at most once in your life.

In common Linux distributions like Ubuntu, installing an older compiler is as easy as using apt or yum:

#Ubuntu
$ sudo apt install build-essential
$ sudo apt install gcc-7 g++-7
#Centos
$ sudo yum install devtoolset-7-gcc*

Now, you would have available your previous compiler, which is still set to default, and the new one. In order to use it for your annoying old code, you have basically three options:

  1. Edit the makefile to select the new compiler version
  2. Set an environmental variable with the path of the new compiler
  3. Change your PATH environmental variable to point to the new compiler first
  4. Change the default compiler

Options 1 and 2 are equivalent and require you to know the path of the compiler. By default, they are generally installed in /usr/bin/. Thus, to compile something using our newly installed g++-7 / gcc-7 you only need to run make or cmake with the new compiler pointed in the CC and CXX variables:

$ make CC=/usr/bin/gcc-7 CXX=/usr/bin/g++-7
#or
$ CC=/usr/bin/gcc-7 CXX=/usr/bin/g++-7 cmake YOUR_ARGUMENTS

Option 3 is a bit more convoluted but quite useful to know. The PATH environmental variable in Linux OS tells where the executable files should be looked for. In order to prepend some folders you just need to do PATH=/my/first/dir:my/second/dir:$PATH and if you want to append them use PATH=/my/first/dir:my/second/dir:$PATH. So when you type in the terminal any name, like cd or ls, the OS tries to find a file named cd in the first directory of the PATH variable, then in the second one and so on, reporting the infamous command not found in case it cannot find it in any directory.

PATH, like any environmental variable, can be set for the whole session using export or it can be set for a single command by setting its value prior to command execution.

$ ls /home/me/myBin
myCommand
#myCommand is a compiled program with execution permisions
PATH=/home/me/myBin:$PATH myCommand
# or 
$ export PATH=/home/me/myBin:$PATH 
$ myCommand

Lastly, in option 4, you can just change the default version of your compiler using update-alternatives in Ubuntu or scl enable in Centos

#Ubuntu
##Add the installed version as an alternative
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 7
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 7
##Check that the aplternative is available
$ sudo update-alternatives --display gcc
$ sudo update-alternatives --display g++
##set the desired version
$ sudo update-alternatives --config gcc 
There are 4 choices for the alternative gcc (providing /usr/bin/gcc).

  Selection    Path              Priority   Status
------------------------------------------------------------
  0            /usr/bin/gcc-4.8   50        auto mode
  1            /usr/bin/gcc-4.8   50        manual mode
  2            /usr/bin/gcc-7     5         manual mode
  3            /usr/bin/gcc-8     4         manual mode
* 4            /usr/bin/gcc-9     9         manual mode

Press <enter> to keep the current choice[*], or type selection number: 4

$ sudo update-alternatives --config g++ 
There are 4 choices for the alternative g++ (providing /usr/bin/g++).

  Selection    Path              Priority   Status
------------------------------------------------------------
  0            /usr/bin/g++-4.8   50        auto mode
  1            /usr/bin/g++-4.8   50        manual mode
  2            /usr/bin/g++-7     5         manual mode
  3            /usr/bin/g++-8     4         manual mode
* 4            /usr/bin/g++-9     9         manual mode

Press <enter> to keep the current choice[*], or type selection number: 4

And now you should be able to compile your old code.

Once you have finished, please, do not forget to set as the default compiler the original version. Failing to do so, you may face some unexpected errors in the future, especially when your machine gets automatically updated.

Author