CLOSE

Why a Cross-Compiler?

A cross-compiler is a compiler capable of creating executable code for a platform different from the one on which the compiler is running. This is essential for developing software for embedded systems, operating systems, or any environment where you can't run a native compiler.

Prerequisites

Before you start, ensure you have the following:

  • A Unix-like operating system (Linux or macOS is preferred).
  • Basic knowledge of compiling software from source.
  • Sufficient disk space (several gigabytes may be required).
  • Development tools: gcc, make, wget, tar, and bzip2.

Steps to Build a 32-bit Cross-Compiler for x86

Step 1: Download the Source Code

You will need the source code for GCC, Binutils, and the C library (e.g., Newlib or Glibc).

# Create a directory for the source code
mkdir -p $HOME/src
cd $HOME/src

# Download GCC
wget https://ftp.gnu.org/gnu/gcc/gcc-12.1.0/gcc-12.1.0.tar.gz
tar -xzf gcc-12.1.0.tar.gz

# Download Binutils
wget https://ftp.gnu.org/gnu/binutils/binutils-2.38.tar.gz
tar -xzf binutils-2.38.tar.gz

# Download Newlib (or Glibc if you prefer)
wget ftp://sourceware.org/pub/newlib/newlib-4.1.0.tar.gz
tar -xzf newlib-4.1.0.tar.gz

Step 2: Create Installation Directory

Decide where you want to install your cross-compiler. This example uses $HOME/opt/cross.

mkdir -p $HOME/opt/cross
export PREFIX="$HOME/opt/cross"
export TARGET=i686-elf
export PATH="$PREFIX/bin:$PATH"

Step 3: Build and Install Binutils

First, build and install Binutils, which provides the assembler, linker, and other tools.

cd $HOME/src
mkdir build-binutils
cd build-binutils
../binutils-2.38/configure --target=$TARGET --prefix=$PREFIX --with-sysroot --disable-nls --disable-werror
make
make install

Step 4: Build and Install GCC (Bootstrap)

Next, build and install GCC. Note that without a C library, you will not be able to use the full C standard library. However, you can still build GCC to produce binaries for your target architecture.

cd $HOME/src
mkdir build-gcc
cd build-gcc
../gcc-12.1.0/configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-languages=c,c++ --without-headers
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc

Step 5: Build and Install C Library (Newlib)

Build and install the C library, which provides the standard C library functions.

cd $HOME/src
mkdir build-newlib
cd build-newlib
../newlib-4.1.0/configure --target=$TARGET --prefix=$PREFIX
make
make install

Step 6: Finalize GCC Build

Now that the C library is available, finalize the GCC build to include full support for C and C++.

cd $HOME/src/build-gcc
../gcc-12.1.0/configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-languages=c,c++ --with-newlib
make all
make install

Verifying the Installation

To verify that your cross-compiler is correctly installed, you can check the version and target architecture.

$PREFIX/bin/$TARGET-gcc --version
$PREFIX/bin/$TARGET-gcc -v

You should see output indicating that GCC is targeting i686-elf.

Complete Bash Script for a 32-bit cross-compiler

The below script will automate the download, extraction, and build process for both GCC and Binutils, installing them into the specified prefix directory ($HOME/opt/cross). After the script completes, you will have a working 32-bit cross-compiler for the x86 architecture.

#!/bin/bash

# Set the installation prefix and target
PREFIX="$HOME/opt/cross"
TARGET=i686-elf
PATH="$PREFIX/bin:$PATH"

# Versions of the tools
GCC_VERSION=12.1.0
BINUTILS_VERSION=2.38

# Directories for sources and build
SRC_DIR="$HOME/src"
BUILD_DIR="$SRC_DIR/build"
mkdir -p $SRC_DIR $BUILD_DIR

# Function to download and extract a tarball
download_and_extract() {
    local url=$1
    local tarball=$(basename $url)
    local dirname=${tarball%.tar.*}

    if [ ! -f $SRC_DIR/$tarball ]; then
        wget -P $SRC_DIR $url
    fi
    if [ ! -d $SRC_DIR/$dirname ]; then
        tar -xf $SRC_DIR/$tarball -C $SRC_DIR
    fi
}

# Download GCC and Binutils sources
download_and_extract https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz
download_and_extract https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz

# Build and install Binutils
mkdir -p $BUILD_DIR/binutils
cd $BUILD_DIR/binutils
$SRC_DIR/binutils-$BINUTILS_VERSION/configure --target=$TARGET --prefix=$PREFIX --with-sysroot --disable-nls --disable-werror
make
make install

# Build and install GCC (Bootstrap)
mkdir -p $BUILD_DIR/gcc
cd $BUILD_DIR/gcc
$SRC_DIR/gcc-$GCC_VERSION/configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-languages=c,c++ --without-headers
make all-gcc
make install-gcc
make all-target-libgcc
make install-target-libgcc

echo "Cross-compiler for $TARGET installed in $PREFIX"

# Verify the installation
$PREFIX/bin/$TARGET-gcc --version

Run the Script:

Execute the script to start the process of building and installing the cross-compiler.

./build-cross-compiler.sh