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.
Fixing Dynamic Library Search
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.
[not recommended] Setting
LD_LIBRARY_PATH
in the shell that executes the build program e.g.,export LD_LIBRARY_PATH='/usr/local/lib/../lib64:/usr/local/lib/gcc/x86_64-pc-linux-gnu/10.2.0/plugin:/usr/local/libexec/gcc/x86_64-pc-linux-gnu/10.2.0' ./my_prog_build_with_gcc_10
This has can potentially break programs build with the system GCC.
Setting
LD_RUN_PATH
in a shell from which the build (linking) runs:export LD_RUN_PATH='/usr/local/lib/../lib64:/usr/local/lib/gcc/x86_64-pc-linux-gnu/10.2.0/plugin:/usr/local/libexec/gcc/x86_64-pc-linux-gnu/10.2.0' g++-10 my_prog.cpp -std=c++20
This will make the binary look for libraries in the given paths before the system ones. The variable need not be set for the execution to work correctly. This setting is safe to use (as far as you avoid using older GCC in the shell that has this set).
[recommended] Setting
rpath
on compilation – this is essentialy the same as the previous option and can be safely automated, see using specs file.[really not recommended] using
ld.so.conf
– this will make all C++ programs use the new GCC’s library, which is not a safe default.
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.