Part 4: Building the Cross-Compilation Toolchain
Overview
The cross-compilation toolchain allows you to build programs for your LFS system from your host system. This chapter builds the initial compiler and libraries in $LFS/tools.
Prerequisites
- Completed Part 1-3
- Logged in as
lfsuser $LFSvariable set- All packages downloaded to
$LFS/sources
Build Order
- Binutils-2.45 (Pass 1)
- GCC-15.2.0 (Pass 1)
- Linux-6.16.1 API Headers
- Glibc-2.42
- Libstdc++ from GCC-15.2.0
General Build Instructions
For each package:
# Extract package
cd $LFS/sources
tar -xf <package>.tar.xz
cd <package-directory>
# Create build directory (if recommended)
mkdir -v build
cd build
# Configure, build, install
../ configure <options>
make
make install
# Clean up
cd $LFS/sources
rm -rf <package-directory>
1. Binutils-2.45 - Pass 1
Purpose: Cross-linker and assembler
Build Time: 1 SBU Disk Space: 700 MB
cd $LFS/sources
tar -xf binutils-2.45.tar.xz
cd binutils-2.45
# Create dedicated build directory
mkdir -v build
cd build
# Configure
../configure --prefix=$LFS/tools \
--with-sysroot=$LFS \
--target=$LFS_TGT \
--disable-nls \
--enable-gprofng=no \
--disable-werror \
--enable-new-dtags \
--enable-default-hash-style=gnu
# Build
make
# Install
make install
# Cleanup
cd $LFS/sources
rm -rf binutils-2.45
Configure Options Explained:
--prefix=$LFS/tools- Install to tools directory--with-sysroot=$LFS- Tell linker where to find libraries--target=$LFS_TGT- Cross-compile for LFS target--disable-nls- Disable internationalization (not needed)--enable-gprofng=no- Don't build gprofng (not needed)--disable-werror- Don't stop on warnings--enable-new-dtags- Use modern RPATH tag--enable-default-hash-style=gnu- Use GNU hash style
2. GCC-15.2.0 - Pass 1
Purpose: Cross-compiler
Build Time: 11 SBU Disk Space: 4.2 GB
cd $LFS/sources
tar -xf gcc-15.2.0.tar.xz
cd gcc-15.2.0
# Extract required dependencies
tar -xf ../mpfr-4.2.2.tar.xz
mv -v mpfr-4.2.2 mpfr
tar -xf ../gmp-6.3.0.tar.xz
mv -v gmp-6.3.0 gmp
tar -xf ../mpc-1.3.1.tar.gz
mv -v mpc-1.3.1 mpc
# For x86_64, set default directory to lib (not lib64)
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
# Create build directory
mkdir -v build
cd build
# Configure
../configure \
--target=$LFS_TGT \
--prefix=$LFS/tools \
--with-glibc-version=2.42 \
--with-sysroot=$LFS \
--with-newlib \
--without-headers \
--enable-default-pie \
--enable-default-ssp \
--disable-nls \
--disable-shared \
--disable-multilib \
--disable-threads \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
# Build
make
# Install
make install
# Create limits.h header
cd ..
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
`dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include/limits.h
# Cleanup
cd $LFS/sources
rm -rf gcc-15.2.0
Configure Options Explained:
--target=$LFS_TGT- Cross-compile for LFS target--with-glibc-version=2.42- Specify glibc version--with-newlib- No C library available yet--without-headers- No C headers available yet--enable-default-pie- Position Independent Executables--enable-default-ssp- Stack Smashing Protector--disable-shared- Build static libraries only--disable-multilib- Disable multi-arch support--enable-languages=c,c++- Only C and C++
3. Linux-6.16.1 API Headers
Purpose: Kernel headers for glibc
Build Time: <0.1 SBU Disk Space: 1.6 GB
cd $LFS/sources
tar -xf linux-6.16.1.tar.xz
cd linux-6.16.1
# Ensure tree is clean
make mrproper
# Extract headers
make headers
# Install to temporary location
find usr/include -type f ! -name '*.h' -delete
cp -rv usr/include $LFS/usr
# Cleanup
cd $LFS/sources
rm -rf linux-6.16.1
4. Glibc-2.42
Purpose: GNU C Library
Build Time: 4.5 SBU Disk Space: 850 MB
cd $LFS/sources
tar -xf glibc-2.42.tar.xz
cd glibc-2.42
# Create symlink for LSB compliance
case $(uname -m) in
i?86) ln -sfv ld-linux.so.2 $LFS/lib/ld-lsb.so.3
;;
x86_64) ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64
ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64/ld-lsb-x86-64.so.3
;;
esac
# Apply patch (if needed - check LFS docs)
# patch -Np1 -i ../glibc-2.42-fhs-1.patch
# Create build directory
mkdir -v build
cd build
# Ensure proper tools are used
echo "rootsbindir=/usr/sbin" > configparms
# Configure
../configure \
--prefix=/usr \
--host=$LFS_TGT \
--build=$(../scripts/config.guess) \
--enable-kernel=5.4 \
--with-headers=$LFS/usr/include \
--disable-nscd \
libc_cv_slibdir=/usr/lib
# Build
make
# Install
make DESTDIR=$LFS install
# Fix hardcoded path
sed '/RTLDLIST=/s@/usr@@g' -i $LFS/usr/bin/ldd
# Sanity check
echo 'int main(){}' | $LFS_TGT-gcc -xc -
readelf -l a.out | grep ld-linux
# Should show: [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
# or [Requesting program interpreter: /lib/ld-linux.so.2] for 32-bit
rm -v a.out
# Cleanup
cd $LFS/sources
rm -rf glibc-2.42
Configure Options Explained:
--host=$LFS_TGT- Cross-compile for LFS--build=$(../scripts/config.guess)- Auto-detect build system--enable-kernel=5.4- Minimum kernel version--with-headers=$LFS/usr/include- Use Linux headers--disable-nscd- Don't build name service cache daemonlibc_cv_slibdir=/usr/lib- Install shared libraries to /usr/lib
5. Libstdc++ from GCC-15.2.0
Purpose: C++ standard library
Build Time: 0.4 SBU Disk Space: 1.1 GB
cd $LFS/sources
tar -xf gcc-15.2.0.tar.xz
cd gcc-15.2.0
# Create build directory
mkdir -v build
cd build
# Configure
../libstdc++-v3/configure \
--host=$LFS_TGT \
--build=$(../config.guess) \
--prefix=/usr \
--disable-multilib \
--disable-nls \
--disable-libstdcxx-pch \
--with-gxx-include-dir=/tools/$LFS_TGT/include/c++/15.2.0
# Build
make
# Install
make DESTDIR=$LFS install
# Remove libtool archive files
rm -v $LFS/usr/lib/lib{stdc++{,exp,fs},supc++}.la
# Cleanup
cd $LFS/sources
rm -rf gcc-15.2.0
Verification
After completing the cross-toolchain, verify it works:
# Test compiler
echo 'int main(){}' | $LFS_TGT-gcc -xc -
readelf -l a.out | grep ld-linux
rm a.out
# Expected output:
# [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
# or
# [Requesting program interpreter: /lib/ld-linux.so.2]
Troubleshooting
Issue: configure fails with "C compiler cannot create executables"
Solution: Verify $LFS and $LFS_TGT are set:
echo $LFS
echo $LFS_TGT
Issue: make fails with permission errors
Solution: Ensure you're the lfs user and directories have correct ownership:
whoami # Should be: lfs
ls -ld $LFS/tools
Issue: Cannot find headers
Solution: Verify Linux headers installed:
ls $LFS/usr/include/linux
Next Steps
Cross-toolchain complete! Proceed to:
- Part 5: Build temporary tools using cross-compiler
- Part 6: Enter chroot environment
- Part 7: Build final LFS system
Important Notes
- Never skip sanity checks
- Save build logs for troubleshooting
- Each package should be built in the order shown
- Clean up source directories after each build to save space