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
, andbzip2
.
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