#!/bin/bash # SPDX-License-Identifier: GPL-2.0-or-later # Copyright(c) 2023 Brian Witte # define urls of the release tarballs LIBBPF_URL="https://github.com/libbpf/libbpf/archive/refs/tags/v1.2.2.tar.gz" BPFTOOL_URL="https://github.com/libbpf/bpftool/releases/download/v7.2.0/bpftool-libbpf-v7.2.0-sources.tar.gz" # define where to extract the libraries LIBBPF_DIR="libbpf" BPFTOOL_DIR="bpftool" # create directories mkdir -p "$LIBBPF_DIR" "$BPFTOOL_DIR" # download and extract libraries echo "Fetching and extracting libbpf..." curl -Ls "$LIBBPF_URL" | tar -xz -C "$LIBBPF_DIR" --strip-components=1 echo "Fetching and extracting bpftool..." curl -Ls "$BPFTOOL_URL" | tar -xz -C "$BPFTOOL_DIR" --strip-components=1 echo "Libraries fetched and extracted successfully." base=$PWD cd bpftool/src && make && make install cd $base cd libbpf/src && make && make install TOOLCHAIN_SCRIPT_BASE_DIR=$PWD GCC_COMMIT_HASH=ac9c81dd76cfc34ed53402049021689a61c6d6e7 BINUTILS_COMMIT_HASH=8ea1e363b92243b0562e4a4a360a582e368884a8 GCC_BPF_PATCHES=false PREFIX="$HOME/root-bpf" BUILD_DIR="/tmp/root-bpf-build" echo "Build directory set to: $BUILD_DIR" echo "Prefix set to: $PREFIX" mkdir -p "$BUILD_DIR" cd "$BUILD_DIR" install_dependencies() { echo "Installing necessary dependencies..." apt-get update if ! apt-get install -y \ libgmp-dev \ libmpfr-dev \ libmpc-dev \ texinfo \ flex \ bison \ make \ curl \ git \ file \ gcc \ g++ \ gettext \ libc6 \ libzstd1 \ zlib1g \ libgmp10 \ libmpc3 \ libmpfr6 \ libzstd1; then echo "Error installing dependencies. Aborting." exit 1 fi } clone_repositories() { echo "Cloning GCC and Binutils repositories into $BUILD_DIR" if [ ! -d "$BUILD_DIR/gcc" ]; then echo "Cloning the GCC repository..." if ! git clone https://gcc.gnu.org/git/gcc.git "$BUILD_DIR/gcc"; then echo "Error cloning GCC repository. Aborting." exit 1 fi if [ "$CI_MODE" = false ]; then (cd "$BUILD_DIR/gcc" && git checkout "$GCC_COMMIT_HASH") fi else echo "GCC repository already exists, skipping clone." fi if [ ! -d "$BUILD_DIR/binutils-gdb" ]; then echo "Cloning the Binutils repository..." if ! git clone https://sourceware.org/git/binutils-gdb.git "$BUILD_DIR/binutils-gdb"; then echo "Error cloning Binutils repository. Aborting." exit 1 fi if [ "$CI_MODE" = false ]; then (cd "$BUILD_DIR/binutils-gdb" && git checkout "$BINUTILS_COMMIT_HASH") fi else echo "Binutils repository already exists, skipping clone." fi } apply_patches() { cd $TOOLCHAIN_SCRIPT_BASE_DIR echo "Applying patches..." patch_files=(gcc-bpf/0*.patch) # check if patch files are found if [ -f "${patch_files[0]}" ]; then for patch in "${patch_files[@]}"; do echo "Applying $patch" if ! patch -p1 -d "$BUILD_DIR" <"$patch"; then echo "Failed to apply patch: $patch" exit 1 fi done else echo "No patch files found in gcc-bpf/ dir" fi } build_binutils() { echo "Building Binutils..." mkdir -p "$BUILD_DIR/binutils-build" && cd "$BUILD_DIR/binutils-build" echo $PWD if ! ../binutils-gdb/configure --target=bpf-unknown-none --prefix="$PREFIX"; then echo "Error running configure for Binutils. Aborting." exit 1 fi # if ! make -j$(nproc); then if ! make -j16; then echo "Error compiling Binutils. Aborting." exit 1 fi if ! make install; then echo "Error installing Binutils. Aborting." exit 1 fi cd .. } build_gcc() { echo "Building GCC..." mkdir -p "$BUILD_DIR/gcc-build" && cd "$BUILD_DIR/gcc-build" if ! ../gcc/configure --target=bpf-unknown-none --prefix="$PREFIX" --disable-multilib --enable-languages=c; then echo "Error running configure for GCC. Aborting." exit 1 fi #if ! make -j$(nproc); then if ! make -j16; then echo "Error compiling GCC. This step may take a while. Aborting." exit 1 fi if ! make install; then echo "Error installing GCC. Aborting." exit 1 fi cd .. } update_environment() { echo "" echo "Execute below in shell or add to .bashrc, .zshrc, etc." echo "export PATH=$PREFIX/bin:\$PATH" echo "" } verify_installation() { echo "Verifying installation..." if ! $PREFIX/bin/bpf-unknown-none-gcc --version; then echo "GCC installation verification failed. Aborting." exit 1 fi if ! $PREFIX/bin/bpf-unknown-none-as --version; then echo "Binutils installation verification failed. Aborting." exit 1 fi echo "" echo "GCC and Binutils successfully installed!" } # main program install_dependencies clone_repositories if [ "$GCC_BPF_PATCHES" = true ]; then apply_patches fi build_binutils build_gcc verify_installation update_environment echo "Toolchain installation completed successfully."