How to choose the default gcc and g++ version?
First erase the current update-alternatives
setup for gcc
and g++
:
sudo update-alternatives --remove-all gcc
sudo update-alternatives --remove-all g++
Install Packages
It seems that both gcc-4.3
and gcc-4.4
are installed after install build-essential. However, we can explicitly install the following packages:
sudo apt-get install gcc-4.3 gcc-4.4 g++-4.3 g++-4.4
Install Alternatives
Symbolic links cc
and c++
are installed by default. We will install symbol links for gcc
and g++
, then link cc
and c++
to gcc
and g++
respectively. (Note that the 10
, 20
and 30
options are the priorities for each alternative, where a bigger number is a higher priority.)
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 10
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.3 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 20
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
sudo update-alternatives --set cc /usr/bin/gcc
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
sudo update-alternatives --set c++ /usr/bin/g++
Configure Alternatives
The last step is configuring the default commands for gcc
, g++
. It's easy to switch between 4.3 and 4.4 interactively:
sudo update-alternatives --config gcc
sudo update-alternatives --config g++
Or switch using script:
#!/bin/sh
if [ -z "$1" ]; then
echo "usage: $0 version" 1>&2
exit 1
fi
if [ ! -f "/usr/bin/gcc-$1" ] || [ ! -f "/usr/bin/g++-$1" ]; then
echo "no such version gcc/g++ installed" 1>&2
exit 1
fi
update-alternatives --set gcc "/usr/bin/gcc-$1"
update-alternatives --set g++ "/usr/bin/g++-$1"
execute in terminal :
gcc -v
g++ -v
Okay, so that part is fairly simple. The tricky part is that when you issue the command GCC it is actually a sybolic link to which ever version of GCC you are using. What this means is we can create a symbolic link from GCC to whichever version of GCC we want.
- You can see the symbolic link :
ls -la /usr/bin | grep gcc-4.4 ls -la /usr/bin | grep g++-4.4
- So what we need to do is remove the GCC symlink and the G++ symlink and then recreate them linked to GCC 4.3 and G++ 4.3:
rm /usr/bin/gcc rm /usr/bin/g++ ln -s /usr/bin/gcc-4.3 /usr/bin/gcc ln -s /usr/bin/g++-4.3 /usr/bin/g++
- Now if we check the symbolic links again we will see GCC & G++ are now linked to GCC 4.3 and G++ 4.3:
ls -la /usr/bin/ | grep gcc ls -la /usr/bin/ | grep g++
- Finally we can check our GCC -v again and make sure we are using the correct version:
gcc -v g++ -v
Is this really desirable? There are ABI changes between gcc
versions. Compiling something with one version (eg the entire operating system) and then compiling something else with another version, can cause conflict.
For example, kernel modules should always be compiled with the same version of gcc
used to compile the kernel. With that in mind, if you manually altered the symlink between /usr/bin/gcc
and the version used in your version of Ubuntu, future DKMS-built modules might use the wrong gcc
version.
If you just want to build things with a different version of gcc
, that's easy enough, even with makescripts. For example, you can pass in the version of gcc
in the CC
environment variable:
CC="gcc-4.5" ./configure
CC="gcc-4.5" make
You might not need it on the make command (configure scripts usually pull it in) but it doesn't hurt.
Edit:
This assumes that you have installed the version first, with e.g.:
sudo apt install gcc-4.9 g++-4.9
Original:
And here is a one-liner for those who are lazy, just change change the number at the end to the version you want. It will make the change for gcc and/or g++
ls -la /usr/bin/ | grep -oP "[\S]*(gcc|g\+\+)(-[a-z]+)*[\s]" | xargs bash -c 'for link in ${@:1}; do sudo ln -s -f "/usr/bin/${link}-${0}" "/usr/bin/${link}"; done' 4.9
In this example I switched to 4.9
There are no error checks and what not in this example, so you might want to check what will be run before you run it. Just add echo before sudo. For completeness I provide check line as well:
ls -la /usr/bin/ | grep -oP "[\S]*(gcc|g\+\+)(-[a-z]+)*[\s]" | xargs bash -c 'for link in ${@:1}; do echo sudo ln -s -f "/usr/bin/${link}-${0}" "/usr/bin/${link}"; done' 4.9
The output from the check should be something like:
sudo ln -s -f /usr/bin/g++-4.9 /usr/bin/g++
sudo ln -s -f /usr/bin/gcc-4.9 /usr/bin/gcc
sudo ln -s -f /usr/bin/gcc-ar-4.9 /usr/bin/gcc-ar
sudo ln -s -f /usr/bin/gcc-nm-4.9 /usr/bin/gcc-nm
sudo ln -s -f /usr/bin/gcc-ranlib-4.9 /usr/bin/gcc-ranlib
sudo ln -s -f /usr/bin/x86_64-linux-gnu-g++-4.9 /usr/bin/x86_64-linux-gnu-g++
sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-4.9 /usr/bin/x86_64-linux-gnu-gcc
sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-ar-4.9 /usr/bin/x86_64-linux-gnu-gcc-ar
sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-nm-4.9 /usr/bin/x86_64-linux-gnu-gcc-nm
sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-ranlib-4.9 /usr/bin/x86_64-linux-gnu-gcc-ranlib
You can check the version after with:
gcc --version
Semi-detailed explanation:
- ls -la /usr/bin/ lists all files in /usr/bin
- | pipe (send) the output to the next command
- grep -oP matches the search regex per line. o only shows the result not the entire matched line. P tells grep to use perl-regex. I will not go into regex here, read up on it if you want to.
- xargs simply put, it gathers the results that are piped to it and send all of them to the end. i.e. to the command following xargs
- bash well, it's bash. The c flag tells it to use the string as a command. In this example it loops over the arguments sent from xargs by skipping the first (0th) argument, in this case the loop skips 4.9. The 0th argument is used in the loop to change the link.
- ln -s -f The s flag makes a symbolic link, f forces unlinking first if needed.
I usually configure also related gcc tools (gcc-ar
, ...) as slaves, so you can switch all of them at once:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 10 \
--slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-4.3 \
--slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-4.3 \
--slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-4.3
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 20 \
--slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-4.4 \
--slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-4.4 \
--slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-4.4
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.3 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 20
Then to select the default one:
sudo update-alternatives --config gcc
sudo update-alternatives --config g++