The Bootstrap Process: Pass One and Pass Two
The Bootstrap Process: Pass One and Pass Two
Bootstrapping a new distribution presents a circular dependency problem: - To build the C library (glibc), you need a C compiler (gcc). - To build a functional C compiler (gcc), you need the C library headers and startup objects (libc.so, crt1.o).
The Circular Bootstrap Paradox
+---------------------------+
| GCC needs libc headers |
+-------------+-------------+
|
v
+---------------------------+
| libc needs GCC compiler |
+---------------------------+
To break this loop without poisoning the target distribution with host binaries, distro builders employ a multi-pass bootstrap process.
Pass 1: The Bare-Metal Cross-Compiler
In Pass 1, we compile a stripped-down, static cross-compiler that runs on the host system:
Install Linux API Headers: Extract kernel headers directly into
$SYSROOT/usr/include.$ make mrproper $ make headers_install INSTALL_HDR_PATH=$SYSROOT/usrBuild Cross-Binutils (Pass 1): Configured with
--target=$TARGETand--with-sysroot=$SYSROOT.$ ../binutils/configure \ --prefix=$TOOLS \ --with-sysroot=$SYSROOT \ --target=$TARGET \ --disable-nls \ --disable-werror $ make && make installBuild GCC (Pass 1 - Static / Inhibit libc): Configure GCC with
--without-headers,--with-newlib, and--disable-shared. This builds a bare C-only compiler without thread support or dynamic linking capabilities:$ ../gcc/configure \ --target=$TARGET \ --prefix=$TOOLS \ --with-glibc-version=2.39 \ --with-sysroot=$SYSROOT \ --without-headers \ --disable-nls \ --disable-shared \ --disable-threads \ --enable-languages=c $ make all-gcc all-target-libgcc && make install-gcc install-target-libgcc
The Intermediate Bridge: Compiling the Target C Library
Now that we possess $TOOLS/bin/$TARGET-gcc (a compiler capable of emitting target machine code without needing a pre-existing target libc), we compile glibc or musl:
$ CC="$TARGET-gcc" ../glibc/configure \
--prefix=/usr \
--host=$TARGET \
--build=$(../glibc/scripts/config.guess) \
--enable-kernel=4.19 \
--with-headers=$SYSROOT/usr/include \
libc_cv_slibdir=/usr/lib
$ make && make DESTDIR=$SYSROOT installPass 2: The Full Cross-Compiler and Native Chroot Tools
With the target C library now safely installed inside $SYSROOT/usr/lib and $SYSROOT/usr/include:
Rebuild GCC (Pass 2): Build a full compiler targeting
$TARGETwith C++ support, thread support (pthreads), and shared library support enabled.Compile Core Utilities for Target: Using the Pass 2 cross-compiler, build Bash, Coreutils, Sed, Grep, Gawk, and Make, installing them into
$SYSROOT.The Pivot (Entering Chroot): Mount host
/dev,/proc, and/sysinto$SYSROOTand switch into the target rootfs usingchroot:# chroot $SYSROOT /usr/bin/bashFrom this point forward, every package is compiled natively from inside the clean environment. The host system’s tools are severed.