➜ sudo yum -y install dnf
CentOS has a pretty old compiler. While the Software Collections repository contains newer versions, it still has a considerable lag-time. So, why not build GCC from source? As it turns out, it’s not actually that hard.
This tutorial provides the steps necessary to compile and install a newer version of GCC, version 10.2.0 to be specific, on CentOS 7. The GCC front-ends for C, C++, and Fortran are included. You should be familiar with command-line tools, CentOS, and the compiling and installing software on Linux. Shell commands are provided in both Bash, the native shell on CentOS 7, and fish because it has standards.
If you aren’t using the DNF package manager yet, grab that.
➜ sudo yum -y install dnf
Install the dependencies necessary to build GCC.
➜ sudo dnf -y install bzip2 wget gcc gcc-c++ gmp-devel mpfr-devel libmpc-devel make
Download the latest release, GCC 10.2.0 in this case, available here.
➜ wget https://ftp.gnu.org/gnu/gcc/gcc-10.2.0/gcc-10.2.0.tar.xz
Download the corresponding signature file.
➜ wget https://ftp.gnu.org/gnu/gcc/gcc-10.2.0/gcc-10.2.0.tar.xz.sig
Verify the archive’s signature.
➜ gpg --keyserver-options auto-key-retrieve gcc-10.2.0.tar.xz.sig gpg: Signature made Thu 23 Jul 2020 01:57:41 AM CDT using RSA key ID FC26A641 gpg: requesting key FC26A641 from hkp server keys.gnupg.net gpg: key 981C74C7: public key "Richard Guenther <email@example.com>" imported gpg: no ultimately trusted keys found gpg: Total number processed: 1 gpg: imported: 1 gpg: Good signature from "Richard Guenther <firstname.lastname@example.org>" gpg: aka "Richard Guenther (Work) <email@example.com>" gpg: aka "Richard Guenther <firstname.lastname@example.org>" gpg: aka "Richard Guenther (GCC) <email@example.com>" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 1397 5A70 E63C 361C 73AE 69EF 6EEB 81F8 981C 74C7 Subkey fingerprint: 7F74 F97C 1034 68EE 5D75 0B58 3AB0 0996 FC26 A641
Here, the option
--keyserver-options auto-key-retrieve will automatically import the signing key from the default key server.
The signature is valid if
Good signature is output.
Otherwise, the signature is bad and you must re-download the source archive.
There are potential privacy concerns when automatically downloading the key this way, as described for the
Extract the archive.
➜ tar xf gcc-10.2.0.tar.xz
Make a build directory.
➜ mkdir gcc-10.2.0-build
Change into the build directory.
➜ cd gcc-10.2.0-build
Run the configure script to prepare the build.
➜ ../gcc-10.2.0/configure --enable-languages=c,c++,fortran \ --disable-multilib --prefix=$HOME/.gcc/10.2.0
GCC is configured to install to the user’s home directory here, but can easily be set to install elsewhere on the system by changing the value for the
# Bash ➜ make -j$(nproc) # fish ➜ make -j(nproc)
Wait patiently for GCC to finish compiling itself.
➜ make install
Change out of the build directory.
➜ cd ..
Free up some disk space by deleting the remaining source and build artifacts.
➜ rm -rf gcc-10.2.0 gcc-10.2.0-build gcc-10.2.0.tar.xz
Setting the relevant environment variables should cause most build tools to recognize find the new compilers as well as link to the relevant libraries. The shell variables are configured to persist across shell sessions below.
CC variable to the path to the C compiler.
# Bash ➜ echo "export CC=$HOME/.gcc/10.2.0/bin/gcc" >> ~/.bashrc ➜ source ~/.bashrc # fish ➜ set -Ux CC ~/.gcc/10.2.0/bin/gcc
CXX variable to the path of the C++ compiler.
# Bash ➜ echo "export CXX=$HOME/.gcc/10.2.0/bin/g++" >> ~/.bashrc ➜ source ~/.bashrc # fish ➜ set -Ux CXX ~/.gcc/10.2.0/bin/g++
FC variable to the path of the Fortran compiler.
# Bash ➜ echo "export FC=$HOME/.gcc/10.2.0/bin/gfortran" >> ~/.bashrc ➜ source ~/.bashrc # fish ➜ set -Ux FC ~/.gcc/10.2.0/bin/gfortran
Prepend the compiler’s executable directory,
bin, to the
PATH environment variable.
# Bash ➜ echo "export PATH=$HOME/.gcc/10.2.0/bin:$PATH" >> ~/.bashrc ➜ source ~/.bashrc # fish ➜ fish_add_path -p ~/.gcc/10.2.0/bin
Prepend the compiler’s library directory,
lib64, to the
LD_LIBRARY_PATH environment variable.
# Bash ➜ echo "export LD_LIBRARY_PATH=$HOME/.gcc/10.2.0/lib64:$LD_LIRBARY_PATH" >> ~/.bashrc ➜ source ~/.bashrc # fish ➜ set -pUx LD_LIBRARY_PATH ~/.gcc/10.2.0/lib64
When using CMake, it is also possible to set certain CMake variables instead of the environment variables. This isolates the potential effects from setting environment variables globally, which may incidentally effect other builds. Set these variables in the CMake cache like so.
➜ cmake \ -DCMAKE_C_COMPILER=$HOME/.gcc/10.2.0/bin/gcc \ -DCMAKE_CXX_COMPILER=$HOME/.gcc/10.2.0/bin/g++ \ -DCMAKE_Fortran_COMPILER=$HOME/.gcc/10.2.0/bin/gfortran \ -DCMAKE_PREFIX_PATH=$HOME/.gcc/10.2.0 \ -B build -S .
When building artifacts that will be deployed elsewhere, take care to ensure that the relevant standard libraries are available to the binary. This is usually accomplished by linking them in statically.