Building GCC

Sometimes I have the peculiar need to use a specific version of GCC, which may not be installed on a system or VM I am using. This is usually related to in situ as I am building a library that has to match a particular solver's GCC. Here are some notes about building GCC

GCC 7.1.0

This version of GCC is fairly new.

Get these tarballs:

Building

We are building and installing to a location that will allow us to have several GCC installations. When you are done, add /usr/local/gcc/7.1.0/bin to your path and use gcc-7.1, g++-7.1, and gfortran-7.1 as your compilers.

# Get sources
wget http://wwww.netgull.com/gcc/releases/gcc-7.1.0/gcc-7.1.0.tar.gz
wget --no-check-certificate https://ftp.gnu.org/gnu/gmp/gmp-6.1.2.tar.bz2
wget http://www.mpfr.org/mpfr-current/mpfr-3.1.5.tar.gz
wget ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz

# Set up build area
tar zxvf gcc-7.1.0.tar.gz
cd gcc-7.1.0
mkdir build
cd build
mkdir install

# Build GMP
bunzip2 ../../gmp-6.1.2.tar.bz2
tar xvf ../../gmp-6.1.2.tar
cd gmp-6.1.2
./configure --prefix=`pwd`/../install --disable-shared
make ; make install
cd ..

# Build MPFR
tar zxvf ../../mpfr-3.1.5.tar.gz
cd mpfr-3.1.5
./configure --prefix=`pwd`/../install --disable-shared --with-gmp=`pwd`/../install
make ; make install
cd ..

# Building MPC
tar zxvf ../../mpc-1.0.3.tar.gz
cd mpc-1.0.3
./configure --prefix=`pwd`/../install --disable-shared --with-gmp=`pwd`/../install --with-mpfr=`pwd`/../install
make ; make install
cd ..

../configure --prefix=/usr/local/gcc/7.1.0 --program-suffix=-7.1 --disable-multilib \
 --with-gmp=`pwd`/install --with-mpfr=`pwd`/install --with-mpc=`pwd`/install
make -j 2
sudo make install

Shared Library Runtime Issue

If you create a new C++ shared library using the new compiler then it will want to link to the stdc++ library, which may result in a dependency on libstdc++.so.6, which will default to the system stdc++ library. That library might be too old to run your programs! If you ldd your library, you may see that the stdc++ library points to /usr/lib64/libstdc++.so.6 and that is not what you want. Note the error messages about missing GLIBCXX versions. This means that the program using the shared library will not run as the shared library will not be successfully loaded.

[bjw@brawn lib]$ ldd libXDBLib.so 
./libXDBLib.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./libXDBLib.so)
./libXDBLib.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./libXDBLib.so)
./libXDBLib.so: /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by ./libXDBLib.so)
./libXDBLib.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./libXDBLib.so)
./libXDBLib.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./libXDBLib.so)
       linux-vdso.so.1 =>  (0x00007fffc03e0000)
       libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b46f38e1000)
       libdl.so.2 => /lib64/libdl.so.2 (0x00002b46f3afe000)
       libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b46f3d02000)
       libm.so.6 => /lib64/libm.so.6 (0x00002b46f4002000)
       libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b46f4286000)
       libc.so.6 => /lib64/libc.so.6 (0x00002b46f4494000)
       /lib64/ld-linux-x86-64.so.2 (0x000000319dc00000)

You will need to put the path to the new compiler's stdc++ library into the LD_LIBRARY_PATH to get things to run smoothly when you have a shared library dependency. One way to do this is to use the env command when running the program, or in this case the ldd command. Note how the libstdc++ library points where we want and there are no error messages. Another way to work around this problem is to relink the program, adding -Wl,-rpath,/usr/local/gcc/7.1.0/lib64 to the link line.

[bjw@brawn lib]$ env LD_LIBRARY_PATH=/usr/local/gcc/7.1.0/lib64 ldd libXDBLib.so 
       linux-vdso.so.1 =>  (0x00007fff7f5fd000)
       libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b4da4088000)
       libdl.so.2 => /lib64/libdl.so.2 (0x00002b4da42a5000)
       libstdc++.so.6 => /usr/local/gcc/7.1.0/lib64/libstdc++.so.6 (0x00002b4da44a9000)
       libm.so.6 => /lib64/libm.so.6 (0x00002b4da4856000)
       libgcc_s.so.1 => /usr/local/gcc/7.1.0/lib64/libgcc_s.so.1 (0x00002b4da4ada000)
       libc.so.6 => /lib64/libc.so.6 (0x00002b4da4cf1000)
       /lib64/ld-linux-x86-64.so.2 (0x000000319dc00000)

This issue comes up a few times when building 3rd party libraries during the VisIt build process. Adding the new compiler's lib64 directory to the shell's LD_LIBRARY_PATH is the way to go.

export LD_LIBRARY_PATH=/usr/local/gcc/7.1.0/lib64:$LD_LIBRARY_PATH

VisIt

I built VisIt with GCC 7.1.0 after a few issues. When I attempted to run it after a make install, it did not run because it could not locate GCC 7.1.0's libstdc++.so.6. To fix this, I copied my GCC 7.1.0's library (/usr/local/gcc/7.1.0/lib64/libstdc++.so.6) into the VisIt 2.12.3/linux-x86_64/lib directory and that fixed things.

GCC 6.1.0

Use the above script for building GCC 7.1.0 to build GCC 6.1.0 by replacing 7.1 with 6.1.

GCC 5.1.0

Use the above script for building GCC 7.1.0 to build GCC 5.1.0 by replacing 7.1 with 5.1.