#!/bin/bash -e # helpers pushd () { command pushd "$@" > /dev/null; } popd () { command popd "$@" > /dev/null; } DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" CPUS=$( cat /proc/cpuinfo | grep processor | wc -l ) cd "$DIR" # toolchain version TOOLCHAIN_VERSION=1 # package versions used GCC_VERSION=8.3.0 BINUTILS_VERSION=2.32 GDB_VERSION=8.2.1 CMAKE_VERSION=3.14.2 CPPCHECK_VERSION=1.87 LLVM_VERSION=8.0.0 SWIG_VERSION=3.0.12 # used only for LLVM compilation # check for installed dependencies DISTRO="$( egrep '^(VERSION_)?ID=' /etc/os-release | sort | cut -d '=' -f 2- | sed 's/"//g' | paste -s -d '-' )" if [ "$DISTRO" == "debian-9" ] || [ "$DISTRO" == "ubuntu-18.04" ]; then DEPS_MANAGER=apt-get DEPS_COMPILE=( coreutils gcc g++ build-essential make # generic build tools wget # used for archive download gnupg # used for archive signature verification tar gzip bzip2 xz-utils # used for archive unpacking zlib1g-dev # zlib library used for all builds libexpat1-dev libipt-dev libbabeltrace-dev liblzma-dev python3-dev texinfo # for gdb libreadline-dev # for cmake and llvm libffi-dev libxml2-dev # for llvm libedit-dev libpcre3-dev automake bison # for swig ) DEPS_RUN=( make # generic build tools tar gzip bzip2 xz-utils # used for archive unpacking zlib1g # zlib library used for all builds libexpat1 libipt1 libbabeltrace1 liblzma5 python3 # for gdb libreadline7 # for cmake and llvm libffi6 libxml2 # for llvm ) elif [ "$DISTRO" == "centos-7" ]; then DEPS_MANAGER=yum DEPS_COMPILE=( coreutils gcc gcc-c++ make # generic build tools wget # used for archive download gnupg2 # used for archive signature verification tar gzip bzip2 xz # used for archive unpacking zlib-devel # zlib library used for all builds expat-devel libipt-devel libbabeltrace-devel xz-devel python36-devel texinfo # for gdb readline-devel # for cmake and llvm libffi-devel libxml2-devel # for llvm libedit-devel pcre-devel automake bison # for swig ) DEPS_RUN=( make # generic build tools tar gzip bzip2 xz # used for archive unpacking zlib # zlib library used for all builds expat libipt libbabeltrace xz-libs python36 # for gdb readline # for cmake and llvm libffi libxml2 # for llvm ) else echo "Unknown distribution: $DISTRO!" exit 1 fi missing="" for dep in ${DEPS_COMPILE[@]}; do if [ "$DEPS_MANAGER" == "apt-get" ]; then if ! dpkg -s $dep >/dev/null 2>/dev/null; then missing="$dep $missing" fi elif [ "$DEPS_MANAGER" == "yum" ]; then if ! yum list installed $dep >/dev/null 2>/dev/null; then missing="$dep $missing" fi else echo "Invalid package manager: $DEPS_MANAGER!" exit 1 fi done if [ "$missing" != "" ]; then echo "Missing dependencies: $missing" exit 1 fi # check installation directory NAME=toolchain-v$TOOLCHAIN_VERSION PREFIX=/opt/$NAME mkdir -p $PREFIX >/dev/null 2>/dev/null || true if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then echo "Please make sure that the directory '$PREFIX' exists and is writable by the current user!" echo echo "If unsure, execute these commands as root:" echo " mkdir $PREFIX && chown $USER:$USER $PREFIX" echo echo "Press when you have created the directory and granted permissions." # wait for the directory to be created while true; do read if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then echo echo "You can't continue before you have created the directory and granted permissions!" echo echo "Press when you have created the directory and granted permissions." else break fi done fi # create archives directory mkdir -p archives # download all archives pushd archives if [ ! -f gcc-$GCC_VERSION.tar.gz ]; then wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz fi if [ ! -f binutils-$BINUTILS_VERSION.tar.gz ]; then wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz fi if [ ! -f gdb-$GDB_VERSION.tar.gz ]; then wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz fi if [ ! -f cmake-$CMAKE_VERSION.tar.gz ]; then wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION.tar.gz fi if [ ! -f swig-$SWIG_VERSION.tar.gz ]; then wget https://github.com/swig/swig/archive/rel-$SWIG_VERSION.tar.gz -O swig-$SWIG_VERSION.tar.gz fi if [ ! -f cppcheck-$CPPCHECK_VERSION.tar.gz ]; then wget https://github.com/danmar/cppcheck/archive/$CPPCHECK_VERSION.tar.gz -O cppcheck-$CPPCHECK_VERSION.tar.gz fi if [ ! -f llvm-$LLVM_VERSION.src.tar.xz ]; then wget http://releases.llvm.org/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.xz wget http://releases.llvm.org/$LLVM_VERSION/cfe-$LLVM_VERSION.src.tar.xz wget http://releases.llvm.org/$LLVM_VERSION/lld-$LLVM_VERSION.src.tar.xz wget http://releases.llvm.org/$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz fi # verify all archives # NOTE: Verification can fail if the archive is signed by another developer. I # haven't added commands to download all developer GnuPG keys because the # download is very slow. If the verification fails for you, figure out who has # signed the archive and download their public key instead. GPG="gpg --homedir .gnupg" KEYSERVER="hkp://keyserver.ubuntu.com" mkdir -p .gnupg chmod 700 .gnupg # verify gcc if [ ! -f gcc-$GCC_VERSION.tar.gz.sig ]; then wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz.sig fi # list of valid gcc gnupg keys: https://gcc.gnu.org/mirrors.html $GPG --keyserver $KEYSERVER --recv-keys 0xC3C45C06 $GPG --verify gcc-$GCC_VERSION.tar.gz.sig gcc-$GCC_VERSION.tar.gz # verify binutils if [ ! -f binutils-$BINUTILS_VERSION.tar.gz.sig ]; then wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz.sig fi $GPG --keyserver $KEYSERVER --recv-keys 0xDD9E3C4F $GPG --verify binutils-$BINUTILS_VERSION.tar.gz.sig binutils-$BINUTILS_VERSION.tar.gz # verify gdb if [ ! -f gdb-$GDB_VERSION.tar.gz.sig ]; then wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz.sig fi $GPG --keyserver $KEYSERVER --recv-keys 0xFF325CF3 $GPG --verify gdb-$GDB_VERSION.tar.gz.sig gdb-$GDB_VERSION.tar.gz # verify cmake if [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt ] || [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt.asc ]; then wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt.asc fi $GPG --keyserver $KEYSERVER --recv-keys 0x7BFB4EDA sha256sum --ignore-missing -c cmake-$CMAKE_VERSION-SHA-256.txt $GPG --verify cmake-$CMAKE_VERSION-SHA-256.txt.asc cmake-$CMAKE_VERSION-SHA-256.txt # verify llvm, cfe, lld, clang-tools-extra if [ ! -f llvm-$LLVM_VERSION.src.tar.xz.sig ]; then wget http://releases.llvm.org/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.xz.sig wget http://releases.llvm.org/$LLVM_VERSION/cfe-$LLVM_VERSION.src.tar.xz.sig wget http://releases.llvm.org/$LLVM_VERSION/lld-$LLVM_VERSION.src.tar.xz.sig wget http://releases.llvm.org/$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig fi # list of valid llvm gnupg keys: https://releases.llvm.org/download.html $GPG --keyserver $KEYSERVER --recv-keys 0x345AD05D $GPG --verify llvm-$LLVM_VERSION.src.tar.xz.sig llvm-$LLVM_VERSION.src.tar.xz $GPG --verify cfe-$LLVM_VERSION.src.tar.xz.sig cfe-$LLVM_VERSION.src.tar.xz $GPG --verify lld-$LLVM_VERSION.src.tar.xz.sig lld-$LLVM_VERSION.src.tar.xz $GPG --verify clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig clang-tools-extra-$LLVM_VERSION.src.tar.xz popd # create build directory mkdir -p build pushd build # compile gcc if [ ! -f $PREFIX/bin/gcc ]; then if [ -d gcc-$GCC_VERSION ]; then rm -rf gcc-$GCC_VERSION fi tar -xvf ../archives/gcc-$GCC_VERSION.tar.gz pushd gcc-$GCC_VERSION ./contrib/download_prerequisites mkdir build && pushd build # influenced by: https://buildd.debian.org/status/fetch.php?pkg=gcc-8&arch=amd64&ver=8.3.0-6&stamp=1554588545 ../configure -v \ --build=x86_64-linux-gnu \ --host=x86_64-linux-gnu \ --target=x86_64-linux-gnu \ --prefix=$PREFIX \ --disable-multilib \ --with-system-zlib \ --enable-checking=release \ --enable-languages=c,c++,fortran \ --enable-gold=yes \ --enable-ld=yes \ --enable-lto \ --enable-bootstrap \ --disable-vtable-verify \ --disable-werror \ --without-included-gettext \ --enable-threads=posix \ --enable-nls \ --enable-clocale=gnu \ --enable-libstdcxx-debug \ --enable-libstdcxx-time=yes \ --enable-gnu-unique-object \ --enable-libmpx \ --enable-plugin \ --enable-default-pie \ --with-target-system-zlib \ --with-tune=generic \ --without-cuda-driver #--program-suffix=$( printf "$GCC_VERSION" | cut -d '.' -f 1,2 ) \ make -j$CPUS # make -k check # run test suite make install popd && popd fi # activate toolchain export PATH=$PREFIX/bin:$PATH export LD_LIBRARY_PATH=$PREFIX/lib64 # compile binutils if [ ! -f $PREFIX/bin/ld.gold ]; then if [ -d binutils-$BINUTILS_VERSION ]; then rm -rf binutils-$BINUTILS_VERSION fi tar -xvf ../archives/binutils-$BINUTILS_VERSION.tar.gz pushd binutils-$BINUTILS_VERSION mkdir build && pushd build # influenced by: https://buildd.debian.org/status/fetch.php?pkg=binutils&arch=amd64&ver=2.32-7&stamp=1553247092 env \ CC=gcc \ CXX=g++ \ CFLAGS="-g -O2" \ CXXFLAGS="-g -O2" \ LDFLAGS="" \ ../configure \ --build=x86_64-linux-gnu \ --host=x86_64-linux-gnu \ --prefix=$PREFIX \ --enable-ld=default \ --enable-gold \ --enable-lto \ --enable-plugins \ --enable-shared \ --enable-threads \ --with-system-zlib \ --enable-deterministic-archives \ --disable-compressed-debug-sections \ --enable-new-dtags \ --disable-werror make -j$CPUS # make -k check # run test suite make install popd && popd fi # compile gdb if [ ! -f $PREFIX/bin/gdb ]; then if [ -d gdb-$GDB_VERSION ]; then rm -rf gdb-$GDB_VERSION fi tar -xvf ../archives/gdb-$GDB_VERSION.tar.gz pushd gdb-$GDB_VERSION mkdir build && pushd build # https://buildd.debian.org/status/fetch.php?pkg=gdb&arch=amd64&ver=8.2.1-2&stamp=1550831554&raw=0 env \ CC=gcc \ CXX=g++ \ CFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \ CXXFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \ CPPFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2 -fPIC" \ LDFLAGS="-Wl,-z,relro" \ PYTHON="" \ ../configure \ --build=x86_64-linux-gnu \ --host=x86_64-linux-gnu \ --prefix=$PREFIX \ --disable-maintainer-mode \ --disable-dependency-tracking \ --disable-silent-rules \ --disable-gdbtk \ --disable-shared \ --without-guile \ --with-system-readline \ --with-expat \ --with-system-zlib \ --with-lzma \ --with-babeltrace \ --with-intel-pt \ --enable-tui \ --with-python=python3 make -j$CPUS make install popd && popd fi # compile cmake if [ ! -f $PREFIX/bin/cmake ]; then if [ -d cmake-$CMAKE_VERSION ]; then rm -rf cmake-$CMAKE_VERSION fi tar -xvf ../archives/cmake-$CMAKE_VERSION.tar.gz pushd cmake-$CMAKE_VERSION # influenced by: https://buildd.debian.org/status/fetch.php?pkg=cmake&arch=amd64&ver=3.13.4-1&stamp=1549799837 echo 'set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip rpath" FORCE)' >> build-flags.cmake echo 'set(CMAKE_USE_RELATIVE_PATHS ON CACHE BOOL "Use relative paths" FORCE)' >> build-flags.cmake echo 'set(CMAKE_C_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C flags" FORCE)' >> build-flags.cmake echo 'set(CMAKE_CXX_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C++ flags" FORCE)' >> build-flags.cmake echo 'set(CMAKE_SKIP_BOOTSTRAP_TEST ON CACHE BOOL "Skip BootstrapTest" FORCE)' >> build-flags.cmake echo 'set(BUILD_CursesDialog ON CACHE BOOL "Build curses GUI" FORCE)' >> build-flags.cmake mkdir build && pushd build ../bootstrap \ --prefix=$PREFIX \ --init=../build-flags.cmake \ --parallel=$CPUS make -j$CPUS # make test # run test suite make install popd && popd fi # compile cppcheck if [ ! -f $PREFIX/bin/cppcheck ]; then if [ -d cppcheck-$CPPCHECK_VERSION ]; then rm -rf cppcheck-$CPPCHECK_VERSION fi tar -xvf ../archives/cppcheck-$CPPCHECK_VERSION.tar.gz pushd cppcheck-$CPPCHECK_VERSION env \ CC=gcc \ CXX=g++ \ PREFIX=$PREFIX \ CFGDIR=$PREFIX/share/cppcheck/cfg \ make -j$CPUS env \ CC=gcc \ CXX=g++ \ PREFIX=$PREFIX \ CFGDIR=$PREFIX/share/cppcheck/cfg \ make install popd fi # compile swig if [ ! -d swig-$SWIG_VERSION/install ]; then if [ -d swig-$SWIG_VERSION ]; then rm -rf swig-$SWIG_VERSION fi tar -xvf ../archives/swig-$SWIG_VERSION.tar.gz mv swig-rel-$SWIG_VERSION swig-$SWIG_VERSION pushd swig-$SWIG_VERSION ./autogen.sh mkdir build && pushd build ../configure --prefix=$DIR/build/swig-$SWIG_VERSION/install make -j$CPUS make install popd && popd fi # compile llvm if [ ! -f $PREFIX/bin/clang ]; then if [ -d llvm-$LLVM_VERSION ]; then rm -rf llvm-$LLVM_VERSION fi tar -xvf ../archives/llvm-$LLVM_VERSION.src.tar.xz mv llvm-$LLVM_VERSION.src llvm-$LLVM_VERSION tar -xvf ../archives/cfe-$LLVM_VERSION.src.tar.xz mv cfe-$LLVM_VERSION.src llvm-$LLVM_VERSION/tools/clang tar -xvf ../archives/lld-$LLVM_VERSION.src.tar.xz mv lld-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/lld tar -xvf ../archives/clang-tools-extra-$LLVM_VERSION.src.tar.xz mv clang-tools-extra-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/clang/tools/extra pushd llvm-$LLVM_VERSION mkdir build && pushd build # activate swig export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH # influenced by: https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-7&arch=amd64&ver=1%3A7.0.1%7E%2Brc2-1%7Eexp1&stamp=1541506173&raw=0 cmake .. \ -DGCC_INSTALL_PREFIX=$PREFIX \ -DCMAKE_C_COMPILER=$PREFIX/bin/gcc \ -DCMAKE_CXX_COMPILER=$PREFIX/bin/g++ \ -DCMAKE_CXX_LINK_FLAGS="-L$PREFIX/lib64 -Wl,-rpath,$PREFIX/lib64" \ -DCMAKE_INSTALL_PREFIX=$PREFIX \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG" \ -DCMAKE_CXX_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \ -DCMAKE_C_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \ -DLLVM_LINK_LLVM_DYLIB=ON \ -DLLVM_INSTALL_UTILS=ON \ -DLLVM_VERSION_SUFFIX= \ -DLLVM_BUILD_LLVM_DYLIB=ON \ -DLLVM_ENABLE_RTTI=ON \ -DLLVM_ENABLE_FFI=ON \ -DLLVM_BINUTILS_INCDIR=$PREFIX/include/ \ -DLLVM_USE_PERF=yes \ -DLIBCLANG_LIBRARY_VERSION=1 \ -DCLANG_ENABLE_BOOTSTRAP=ON make -j$CPUS make -j$CPUS check-clang # run clang test suite make -j$CPUS check-lld # run lld test suite make install popd && popd fi # create README if [ ! -f $PREFIX/README.md ]; then cat >$PREFIX/README.md <$PREFIX/activate <