Revision 6 as of 2021-08-27 11:11:58

Clear message

Build a specific version of gcc

The script below facilitates building your own version of gcc in a location of your choosing.
It was tested with the default gcc compiler installed with Debian Buster, gcc (Debian 8.3.0-6) 8.3.0 and successfully builds versions 11.2.0, 10.3.0, 9.4.0, 8.5.0, 7.5.0, 6.5.0.

build_gcc.sh

#!/bin/bash

# Install a specific gcc version in user space

PROD='gcc'

# Show usage of this script
function usage
{
    echo "Usage: ${BASH_SOURCE[0]}  [--gcc-version=<version>] [--prefix=<directory>] [--build-dir=<directory>]"
    echo '  --gcc-version=<version>  Supply the gcc version to build'
    echo '  --prefix=<directory>     The installation directory'
    echo '  --build-dir=<directory>  The build directory'
    echo '  --help                   Display this usage information'
    echo
    echo 'For every unset option a default is used'
    echo 'All options (set or defaults) are shown at build start.'
    echo
    echo 'This script was tested with the following versions of gcc:'
    echo '11.2.0, 10.3.0, 9.4.0, 8.5.0, 7.5.0, 6.5.0'
}

# Returns true, if version of $1 is greater than $2
function version_gt ()
{
    test "$(printf '%s\n' "$@" | \
        sort -V | \
        head -n 1)" != "${1}"
}

# Iterate over options and set them
shopt -s extglob
while (( $# )); do
    case "${1}" in
        --gcc-version=*)
            VERSION="${1##*=}"
            shift
            ;;
        --prefix=*)
            PREFIX="${1##*=}"
            shift
            ;;
        --build-dir=*)
            BUILDDIR="${1##*=}"
            shift
            ;;
        --help)
            usage
            shift
            ;;
        *)
            echo "Unknown argument '${1}' ignored"
            echo
            usage
            shift
            exit 1
            ;;
    esac
done

# Set default if no option was given
if [[ -z ${VERSION} ]]; then
    VERSION="7.5.0"
fi

if [[ ${VERSION} =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    # The option matches a version string
    WORKDIR="/scratch/${USER}/${PROD}-${VERSION}"
    # Set defaults if no options were given
    if [[ -z ${PREFIX} ]]; then
        PREFIX="${WORKDIR}/install"
    fi
    if [[ -z ${BUILDDIR} ]]; then
        BUILDDIR="${WORKDIR}/build"
    fi
    # Summarize options
    echo 'Using options:'
    echo "- gcc version:       ${VERSION}"
    echo "- prefix directory:  ${PREFIX}"
    echo "- build directory:   ${BUILDDIR}"

    # Create paths used for building and installation
    mkdir -v -p "${WORKDIR}" "${BUILDDIR}" "${PREFIX}" && \
        cd "${WORKDIR}" && \
        # Download gcc
    wget -c "https://ftpmirror.gnu.org/${PROD}/${PROD}-${VERSION}/${PROD}-${VERSION}.tar.gz" && \
        # Extract gcc archive
    tar --overwrite -vxzf "${PROD}-${VERSION}.tar.gz" && \
        cd "${WORKDIR}/${PROD}-${VERSION}" && \
        # Download prerequisites
    contrib/download_prerequisites && \
        cd "${WORKDIR}/build" && \
        # Configure build
    ../${PROD}-"${VERSION}"/configure \
        --build=x86_64-linux-gnu \
        --host=x86_64-linux-gnu \
        --target=x86_64-linux-gnu \
        --prefix="${PREFIX}" \
        --enable-checking=release \
        --enable-languages=c,c++ \
        --disable-nls \
        --disable-multilib \
        --program-suffix="-${VERSION}" && \
        # Start build
    make -s -j "$(nproc)" && \
        # Install
    make install-strip && \
        echo && \
        echo "${PROD}-${VERSION} was successfully built and installed in ${PREFIX}" && \
        exit 0
else
    echo "Version '${VERSION}' does not match a version string of the form n.m.p"
    exit 1
fi

Using your own version of gcc

To use your own version of gcc, either

Show gcc in your PATH

The following alias lists all found gcc's in your PATH, which is helpful for troubleshooting:

alias showgccs='{ echo "PATH;VERSION" && which -a gcc |while read -r GCC; do echo $GCC && $GCC --version |head -n1; done |paste -d";" - - ;} |column -t -s";"'

Building gcc 5.5.0

The following patch enables building gcc 5.5.0 with gcc 8.3.0:

--- x86_64-linux-gnu/libgcc/md-unwind-support.h.orig    2021-08-26 13:55:12.152350756 +0200
+++ x86_64-linux-gnu/libgcc/md-unwind-support.h 2021-08-26 14:03:59.361317827 +0200
@@ -58,7 +58,7 @@
   if (*(unsigned char *)(pc+0) == 0x48
       && *(unsigned long long *)(pc+1) == RT_SIGRETURN_SYSCALL)
     {
-      struct ucontext *uc_ = context->cfa;
+      struct ucontext_t *uc_ = context->cfa;
       /* The void * cast is necessary to avoid an aliasing warning.
          The aliasing warning is correct, but should not be a problem
          because it does not alias anything.  */
@@ -138,7 +138,7 @@
        siginfo_t *pinfo;
        void *puc;
        siginfo_t info;
-       struct ucontext uc;
+       ucontext_t uc;
       } *rt_ = context->cfa;
       /* The void * cast is necessary to avoid an aliasing warning.
          The aliasing warning is correct, but should not be a problem

In case you need this version of gcc, apply the patch to the source before running the configure part of the script.