Compiling GCC 10

You will need to have some g++ installed, the one in your distribution should be sufficient unless you distribution is archaic. Go to some build directory and run the following commands:

# download GCC 10.2
wget ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-10.2.0/gcc-10.2.0.tar.xz
# extract it
tar xaf gcc-10.2.0.tar.xz
# switch to the source dir
cd gcc-10.2.0/
# download sources of prerequisities
./contrib/download_prerequisites
# configure it (based on the Archlinux build)
./configure --program-suffix=-10 \
    --enable-languages=c,c++ \
    --enable-shared \
    --enable-threads=posix \
    --enable-__cxa_atexit \
    --disable-libunwind-exceptions \
    --enable-linker-build-id \
    --enable-lto \
    --enable-plugin \
    --enable-install-libiberty \
    --with-linker-hash-style=gnu \
    --disable-werror \
    --enable-checking=release \
    --disable-multilib
# run parallel build (substitute higher number if you have more CPU cores)
nice make -j4
# actually inctall GCC
sudo make install
# fix dynamic library search, see below

The configuration is the most critical part, here we are setting that the binaries should have suffix -10 (so they are e.g., g++-10 instead of g++), and set some features, most notably we disable languages other then C and C++ (you can enable all with setting --enable-languages=all) and disable multilib (support for 32bit binaries, requires additional dependencies and is generally not very useful these days).

With this settings, GCC is installed to /usr/local/, if you want to change the installation path, you can set --prefix=PATH to a custom path (e.g., in your home if you do not wish to use sudo for the installation).

This build took about an hour on a rather outdated Intel quad core, so please be patient.

One of the problems with having several version of GCC at the same time is that they each come with their own version of the C++ standard library and this library is dynamically linked and therefore the binary will by default pick the original system one (i.e., for the older GCC). This will cause crashes if the program uses any feature that requires library support that was not supported by the older version (or that was configured differently due to difference in configure flags between you system GCC and you new GCC).

GCC’s make install actually points this out and outlines three options to solve this problem (please note that the message is printed several times with different paths). If you have installed GCC to non-standard path using --prefix, you will need to modify the paths in the examples accordingly.

Using specs file

GCC uses a specs file to derive invocation parameter for its subcommands, including liker. Therefore, this file can be used to set default linker options for the given GCC version.

To get a patched specs file for your GCC 10, run the following command:

g++-10 -dumpspecs | sed '/\*link_command:/!b;n;s,$,-rpath /usr/local/lib/../lib64 -rpath /usr/local/lib/gcc/x86_64-pc-linux-gnu/10.2.0/plugin -rpath /usr/local/libexec/gcc/x86_64-pc-linux-gnu/10.2.0 ,' > specs

Now you have to copy the specs to the proper GCC directory:

sudo cp specs /usr/local/lib/gcc/x86_64-pc-linux-gnu/10.2.0/

Note: The sed command finds a line containing string *link_command and appends three sets of -rpath arguments to the next line. This will make GCC 10 use these options on all linker invocations.

Note 2: This is the method used by the gcc-10 module on Aisa (an by older GCC modules since 7.2).

Checking It Works

Compile a program using your GCC and check that it uses the right C++ library:

g++-10 test.cpp -std=c++20
ldd ./a.out | grep libstdc

It should show something like libstdc++.so.6 => /usr/local/lib/../lib64/libstdc++.so.6 (where /usr/local/lib is the important part).

Note: The ldd command can be used to check which dynamically linked libraries a program uses and where they are found in the system. To see the difference, compile the same program using your system’s GCC and compare the output. The path for libstdc++ should differ.