Differences between revisions 11 and 12
Revision 11 as of 2023-04-04 10:41:51
Size: 6043
Editor: bonaccos
Comment: Add table of contents
Revision 12 as of 2023-04-04 14:06:27
Size: 5974
Editor: stroth
Comment: Beautify script
Deletions are marked like this. Additions are marked like this.
Line 16: Line 16:
function usage
{
function usage {
Line 32: Line 31:
function version_gt ()
{
    test "$(printf '%s\n' "$@" | \
        sort -V | \
function version_gt() {
    test "$(printf '%s\n' "$@" |
        sort -V |
Line 41: Line 39:
while (( $# )); do while (($#)); do
Line 43: Line 41:
     --gcc-version=*)
     VERSION="${1##*=}"
            shift
            ;;
    
--prefix=*)
     PREFIX="${1##*=}"
            shift
            ;;
    
--build-dir=*)
     BUILDDIR="${1##*=}"
            shift
            ;;
    
--help)
            usage
            shift
    
exit 0
            ;;
        *)
    
echo "Unknown argument '${1}' ignored"
            echo
            usage
            shift
    
exit 1
            ;;
    --gcc-version=*)
        VERSION="${1##*=}"
        shift
        ;;
--prefix=*)
        PREFIX="${1##*=}"
        shift
        ;;
--build-dir=*)
        BUILDDIR="${1##*=}"
        shift
        ;;
--help)
        usage
        shift
exit 0
        ;;
    *)
echo "Unknown argument '${1}' ignored"
        echo
        usage
        shift
exit 1
        ;;
Line 92: Line 90:
    mkdir -v -p "${WORKDIR}" "${BUILDDIR}" "${PREFIX}" && \
        cd "${WORKDIR}" && \
    mkdir -v -p "${WORKDIR}" "${BUILDDIR}" "${PREFIX}" &&
        cd "${WORKDIR}" &&
Line 95: Line 93:
    wget -c "https://ftpmirror.gnu.org/${PROD}/${PROD}-${VERSION}/${PROD}-${VERSION}.tar.gz" && \      wget -c "https://ftpmirror.gnu.org/${PROD}/${PROD}-${VERSION}/${PROD}-${VERSION}.tar.gz" &&
Line 97: Line 95:
    tar --overwrite -vxzf "${PROD}-${VERSION}.tar.gz" && \
        cd "${WORKDIR}/${PROD}-${VERSION}" && \
     tar --overwrite -vxzf "${PROD}-${VERSION}.tar.gz" &&
        cd "${WORKDIR}/${PROD}-${VERSION}" &&
Line 100: Line 98:
    contrib/download_prerequisites && \
        cd "${WORKDIR}/build" && \
     contrib/download_prerequisites &&
        cd "${WORKDIR}/build" &&
Line 103: Line 101:
    ../${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}" && \
     ../${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}" &&
Line 114: Line 112:
    make -s -j "$(nproc)" && \      make -s -j "$(nproc)" &&
Line 116: Line 114:
    make install-strip && \
        echo && \
        echo "${PROD}-${VERSION} was successfully built and installed in ${PREFIX}" && \
     make install-strip &&
        echo &&
        echo "${PROD}-${VERSION} was successfully built and installed in ${PREFIX}" &&

Build a specific version of the GNU Compiler Collection GCC

The script below facilitates building your own version of GCC in a location of your choosing.
It was tested with the default gcc and g++ compiler installed with Debian Buster, Debian 8.3.0-6 and successfully builds versions 12.2.0, 12.1.0, 11.3.0, 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 '12.2.0, 12.1.0, 11.3.0, 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
        exit 0
        ;;
    *)
        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
  • Download the script
  • Save it as build_gcc.sh

  • Make it executable with:

    chmod +x ./build_gcc.sh
  • Check the script's options by executing it as

    ./build_gcc.sh --help
  • Then execute the script with the options of your choice

Using your new GCC

To use your new version of the GCC:

  1. Prepend its installation path to your PATH environment variable:

    export PATH=/path/to/my/gcc/bin:$PATH
  2. And set the CC and CXX environment variables to the full path of your gcc and g++ binaries:

    export CC=/path/to/my/gcc/bin/gcc-n.m.p
    export CXX=/path/to/my/gcc/bin/g++-n.m.p

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.

Programming/DevTools/BuildGCC (last edited 2023-08-15 12:49:54 by stroth)