#!/bin/bash export LINUX_VERSION="6.12.1" # Function to handle errors error_handler() { local exit_code=$? local line_number=$1 local file_name=$2 echo "Error in file: $file_name, line: $line_number, reason: Command exited with status $exit_code" } # Set the trap to catch errors trap 'error_handler $LINENO $0' ERR set -eo pipefail if [ ! -d "./sources" ]; then echo "Run this script from the right directory" exit 1 fi export BASE_DIR=$(pwd) if [ -z "$ARCH" ]; then echo "You must set a target architecture among supported ones:" echo "i386" echo "x86_64" echo "armv5" exit 1 fi if [ -z "$LFS_TGT" ]; then if [ -z "$GNUEABI" ]; then export GNUEABI="gnu" fi export LFS_TGT="$ARCH-lfs-linux-$GNUEABI" echo "Target triplet set to '$LFS_TGT'. You can specify another one with the LFS_TGT env var." fi if [ ! -d "$LFS_TGT" ]; then export LFS="$(pwd)/out/$LFS_TGT/rootfs" echo "Target rootfs set to '$LFS_TGT'. You can override this by setting the LFS_TGT env var." fi # test bash bash --version echo "" # test rsync rsync --version echo "" # test clang clang --version echo "" # test lld ld --version echo "" make --version echo "" # Create the target directory mkdir -p "$LFS" export STEPS_DIR="$LFS/../steps/" mkdir -vp "$STEPS_DIR" export LFS_TOOLS="$LFS/tools" mkdir -vp "$LFS_TOOLS" export PATH="$LFS_TOOLS/bin/:$PATH" export LFS_BUILD="$LFS/../" unset CFLAGS # Create a directory layout if [ ! -d "$LFS/etc" ]; then mkdir -pv $LFS/{etc,var} $LFS/usr/{bin,lib,sbin} for i in bin lib sbin; do ln -sv usr/$i $LFS/$i done case $ARCH in x86_64) mkdir -pv $LFS/lib64 ;; esac fi # Build binutils if [ ! -f "$STEPS_DIR/binutils" ]; then if [ ! -d "$LFS_BUILD/binutils" ]; then tar -xf "$BASE_DIR/sources/binutils-2.43.tar.zst" mv "binutils-2.43" "$LFS_BUILD/binutils" fi cd "$LFS_BUILD/binutils" mkdir -vp build cd build "../configure" \ --prefix=$LFS_TOOLS \ --with-sysroot=$LFS \ --target=$LFS_TGT \ --with-gnu-as \ --with-gnu-ld \ --enable-ld=default \ --enable-shared \ --disable-nls \ --enable-gprofng=no \ --disable-werror \ --enable-new-dtags \ --disable-multilib \ --disable-libquadmath \ --disable-libquadmath-support \ --enable-plugins \ --enable-deterministic-archives \ --enable-default-hash-style=gnu #make configure-host make -j 32 make -j 32 install cd "$BASE_DIR" #rm -rf "$LFS_BUILD/binutils" touch "$STEPS_DIR/binutils" fi # Install kernel headers if [ ! -f "$STEPS_DIR/linux-headers" ]; then if [ ! -d "$LFS_BUILD/linux" ]; then tar -xzf "$BASE_DIR/sources/linux-$LINUX_VERSION.tar.gz" mv "linux-$LINUX_VERSION" "$LFS_BUILD/linux" fi cd "$LFS_BUILD/linux" make mrproper make headers_install ARCH="$ARCH" INSTALL_HDR_PATH="$LFS/usr" cd "$BASE_DIR" #rm -rf "$LFS_BUILD/linux" touch "$STEPS_DIR/linux-headers" fi # Build gcc if [ ! -f "$STEPS_DIR/gcc-step1" ]; then bash unpack-gcc.sh cd "$LFS_BUILD/gcc/" # # On x86_64 hosts, set the default directory name for 64-bit libraries to “lib” # case $(uname -m) in # x86_64) # sed -e '/m64=/s/lib64/lib/' \ # -i.orig gcc/config/i386/t-linux64 # ;; # esac mkdir -vp build cd build "../configure" \ --target=$LFS_TGT \ --host=$(../config.guess) \ --build=$(../config.guess) \ --prefix=$LFS_TOOLS \ --with-glibc-version=2.40 \ --with-sysroot=$LFS \ --with-newlib \ --disable-gdbtk \ --disable-shared \ --without-headers \ --enable-default-pie \ --enable-default-ssp \ --disable-nls \ --disable-multilib \ --disable-threads \ --disable-libatomic \ --disable-libmudflap \ --disable-libgomp \ --disable-libquadmath \ --disable-libquadmath-support \ --disable-libssp \ --disable-libvtv \ --disable-libstdcxx \ --disable-decimal-float \ --disable-libsanitizer \ --enable-languages=c make -j 32 all-gcc # if build fails add --disable-libsanitizer make -j 32 install-gcc make check-gcc RUNTESTFLAGS=--target_board=$ARCH-sim cd "$BASE_DIR" rm -rf "$LFS_BUILD/gcc/build" # Do not remove the whole gcc directory: we need it for libstdc++ touch "$STEPS_DIR/gcc-step1" fi # From now on use export BUILD_CC=gcc export CC="$LFS_TGT-gcc" export CXX="$LFS_TGT-g++" export AS="$LFS_TGT-as" export LD="$LFS_TGT-ld" export AR="$LFS_TGT-ar" export RANLIB="$LFS_TGT-ranlib" export STRIP="$LFS_TGT-strip" export OBJDUMP="$LFS_TGT-objdump" # remove hardening options for building libraries export CFLAGS="-U_FORTIFY_SOURCE -O2" export CPPFLAGS="-U_FORTIFY_SOURCE -O2" export LD_LIBRARY_PATH_old="$LD_LIBRARY_PATH" unset LD_LIBRARY_PATH # build glibc if [ ! -f "$STEPS_DIR/glibc" ]; then if [ ! -d "$LFS_BUILD/glibc" ]; then tar -xzf "$BASE_DIR/sources/glibc-2.40.tar.gz" mv "glibc-2.40" "$LFS_BUILD/glibc" fi cd "$LFS_BUILD/glibc" mkdir -vp build cd build echo "rootsbindir=/usr/sbin" > configparms echo 'slibdir=/lib' >> configparms echo 'rtlddir=/lib' >> configparms echo 'sbindir=/bin' >> configparms echo 'build-programs=no' >> configparms "../configure" \ --prefix=/usr \ --target=$LFS_TGT \ --host=$LFS_TGT \ --build=$(../scripts/config.guess) \ --with-headers=$LFS/usr/include \ --with-binutils=$LFS_TOOLS/bin \ --without-cvs \ --disable-nls \ --disable-sanity-checks \ --enable-kernel=4.19 \ --disable-debug \ --disable-profile \ --without-selinux \ --without-gd \ --disable-nscd \ --enable-hacker-mode \ libc_cv_slibdir=/usr/lib \ libc_cv_forced_unwind=yes \ libc_cv_c_cleanup=yes make install-bootstrap-headers=yes install_root=$LFS install-headers make -j4 csu/subdir_lib if [ -f "csu/crt1.o" ]; then install csu/crt1.o $LFS/usr/lib fi if [ -f "csu/crti.o" ]; then install csu/crti.o $LFS/usr/lib fi if [ -f "csu/crtn.o" ]; then install csu/crtn.o $LFS/usr/lib fi if [ -f "csu/Scrt1.o" ]; then install csu/Scrt1.o $LFS/usr/lib fi if [ -f "csu/crtbeginS.o" ]; then install csu/crtbeginS.o $LFS/usr/lib fi $LFS_TGT-gcc \ -nostdlib \ -nostartfiles \ -shared \ -x c /dev/null \ -o $LFS/usr/lib/libc.so touch $LFS/usr/include/gnu/stubs.h #export LD_LIBRARY_PATH="$LD_LIBRARY_PATH_old" #make DESTDIR=$LFS install #make install_root="$pkgdir"/usr/$_target install #sed '/RTLDLIST=/s@/usr@@g' -i $LFS/usr/bin/ldd cd "$BASE_DIR" #rm -rf "$LFS_BUILD/glibc" touch "$STEPS_DIR/glibc" fi unset CC unset CXX unset LD unset AS unset AR unset RANLIB unset STRIP unset OBJDUMP export LD_LIBRARY_PATH="$LD_LIBRARY_PATH_old" if [ ! -f "$STEPS_DIR/gcc-step2" ]; then #if [ ! -d "$LFS_BUILD/gcc/build" ]; then # echo "'$LFS_BUILD/gcc/build' directory is supposed to exist. Error." # exit 1 #fi #cd "$LFS_BUILD/gcc/build" cd "$LFS_BUILD/gcc" mkdir -vp build cd build # ../configure is already done "../configure" \ --target=$LFS_TGT \ --host=$(../config.guess) \ --build=$(../config.guess) \ --prefix=$LFS_TOOLS \ --with-glibc-version=2.40 \ --with-sysroot=$LFS \ --enable-c99 \ --enable-long-long \ --enable-default-pie \ --enable-default-ssp \ --disable-nls \ --disable-multilib \ --disable-libatomic \ --disable-libmudflap \ --disable-libgomp \ --disable-libquadmath \ --disable-libquadmath-support \ --disable-libssp \ --disable-libvtv \ --disable-libstdcxx \ --disable-decimal-float \ --disable-libsanitizer \ --enable-languages=c # Repeat this #make -j 32 all-gcc #make -j 32 install-gcc #exit 0 make -j 32 # if build fails add --disable-libsanitizer make -j 32 install cd "$BASE_DIR" #rm -rf "$LFS_BUILD/gcc/build" # Do not remove the whole gcc directory: we need it for libstdc++ touch "$STEPS_DIR/gcc-step2" fi #export CC="$LFS_TGT-gcc" #export CXX="$LFS_TGT-g++" #export AS="$LFS_TGT-as" #export LD="$LFS_TGT-ld" #export AR="$LFS_TGT-ar" #export RANLIB="$LFS_TGT-ranlib" ## remove hardening options for building libraries #export CFLAGS="-U_FORTIFY_SOURCE -O2" #export CPPFLAGS="-U_FORTIFY_SOURCE -O2" #export LD_LIBRARY_PATH_old="$LD_LIBRARY_PATH" #unset LD_LIBRARY_PATH if [ ! -f "$STEPS_DIR/glibc-step2" ]; then if [ ! -d "$LFS_BUILD/glibc/build" ]; then echo "'$LFS_BUILD/glibc/build' is supposed to exist. Error." exit 1 fi cd "$LFS_BUILD/glibc/build" # Configuration is done already # Remove the stub glibc from before rm $LFS/usr/lib/libc.so make -j 32 make -j 32 install_root=$LFS install cd "$BASE_DIR" #rm -rf "$LFS_BUILD/glibc" touch "$STEPS_DIR/glibc-step2" fi #unset CC #unset CXX #unset LD #unset AS #unset AR #unset RANLIB #unset OBJDUMP #export LD_LIBRARY_PATH="$LD_LIBRARY_PATH_old" # build the rest of gcc if [ ! -f "$STEPS_DIR/gcc-step3" ]; then if [ ! -d "$LFS_BUILD/gcc/build" ]; then echo "'$LFS_BUILD/gcc/build' directory is supposed to exist. Error." exit 1 fi cd "$LFS_BUILD/gcc/build" "../configure" \ --target=$LFS_TGT \ --host=$(../config.guess) \ --build=$(../config.guess) \ --prefix=$LFS_TOOLS \ --with-glibc-version=2.40 \ --with-sysroot=$LFS \ --enable-c99 \ --enable-long-long \ --enable-default-pie \ --enable-default-ssp \ --disable-nls \ --disable-multilib \ --disable-libgomp \ --disable-libquadmath \ --disable-libquadmath-support \ --disable-decimal-float \ --enable-languages=c,c++ # Reebuild everything now that we have bootstrapped an initial gcc and glibc make -j 32 # if build fails add --disable-libsanitizer make -j 32 install cd "$BASE_DIR" #rm -rf "$LFS_BUILD/gcc" touch "$STEPS_DIR/gcc-step3" fi # Use the new toolchain export BUILD_CC=gcc export CC="$LFS_TGT-gcc" export CXX="$LFS_TGT-g++" export AS="$LFS_TGT-as" export LD="$LFS_TGT-ld" export AR="$LFS_TGT-ar" export RANLIB="$LFS_TGT-ranlib" export STRIP="$LFS_TGT-strip" export OBJDUMP="$LFS_TGT-objdump" # remove hardening options for building libraries export CFLAGS="-U_FORTIFY_SOURCE -O2" export CPPFLAGS="-U_FORTIFY_SOURCE -O2" export LD_LIBRARY_PATH_old="$LD_LIBRARY_PATH" unset LD_LIBRARY_PATH # test the cross toolchain which -- $LFS_TGT-as || echo $LFS_TGT-as is not in the PATH echo 'int main(){}' | "$LFS_TGT-gcc" -xc - "$LFS_TGT-readelf" -l a.out > test_compiler cat test_compiler | grep ld-linux rm -v a.out test_compiler #cat test_compiler.cpp | "$LFS_TGT-g++" -xc - #"$LFS_TGT-readelf" -l a.out > test_compiler #cat test_compiler | grep ld-linux #rm -v a.out test_compiler # build m4 if [ ! -f "$STEPS_DIR/m4" ]; then if [ ! -d "$LFS_BUILD/m4" ]; then tar -xzf "$BASE_DIR/sources/m4-1.4.19.tar.gz" mv "m4-1.4.19" "$LFS_BUILD/m4" fi cd "$LFS_BUILD/m4" mkdir -vp build cd build echo "rootsbindir=/usr/sbin" > configparms "../configure" \ --prefix=/usr \ --host=$LFS_TGT make -j 32 make DESTDIR=$LFS install "$LFS_TGT-strip" --strip-unneeded $LFS/bin/m4 cd "$BASE_DIR" rm -rf "$LFS_BUILD/m4" touch "$STEPS_DIR/m4" fi # build attr if [ ! -f "$STEPS_DIR/attr" ]; then if [ ! -d "$LFS_BUILD/attr" ]; then tar -xzf "$BASE_DIR/sources/attr-2.5.2.tar.gz" mv "attr-2.5.2" "$LFS_BUILD/attr" fi cd "$LFS_BUILD/attr" mkdir -vp build cd build echo "rootsbindir=/usr/sbin" > configparms "../configure" \ --prefix=/usr \ --disable-static \ --host=$LFS_TGT make -j 32 make DESTDIR=$LFS install cd "$BASE_DIR" touch "$STEPS_DIR/attr" fi # build zlib if [ ! -f "$STEPS_DIR/zlib" ]; then if [ ! -d "$LFS_BUILD/zlib" ]; then tar -xzf "$BASE_DIR/sources/zlib-1.3.1.tar.gz" mv "zlib-1.3.1" "$LFS_BUILD/zlib" fi cd "$LFS_BUILD/zlib" mkdir -vp build cd build "../configure" \ --prefix=$LFS make -j 32 make install cd "$BASE_DIR" touch "$STEPS_DIR/zlib" fi # build ncurses # TODO: fix symlink!!! if [ ! -f "$STEPS_DIR/ncurses" ]; then if [ ! -d "$LFS_BUILD/ncurses" ]; then tar -xzf "$BASE_DIR/sources/ncurses.tar.gz" mv "ncurses-6.3" "$LFS_BUILD/ncurses" fi cd "$LFS_BUILD/ncurses" mkdir -vp build cd build # --build=${CLFS_HOST} \ "../configure" \ --prefix=$LFS/usr \ --with-shared \ --host=${LFS_TGT} \ --without-debug \ --disable-stripping \ --without-ada \ --enable-overwrite \ --with-build-cc=gcc \ --libdir=$LFS/usr/lib make -j 32 make install cd "$BASE_DIR" touch "$STEPS_DIR/ncurses" fi # build bash if [ ! -f "$STEPS_DIR/bash" ]; then if [ ! -d "$LFS_BUILD/bash" ]; then tar -xzf "$BASE_DIR/sources/bash-5.2.tar.gz" mv "bash-5.2" "$LFS_BUILD/bash" fi cd "$LFS_BUILD/bash" mkdir -vp build cd build # --build=${CLFS_HOST} \ "../configure" \ --prefix=$LFS \ --host=${LFS_TGT} \ --without-bash-malloc \ --enable-threads \ --with-curses make -j 32 make install cd "$BASE_DIR" touch "$STEPS_DIR/bash" fi # build bzip2 if [ ! -f "$STEPS_DIR/bzip2" ]; then if [ ! -d "$LFS_BUILD/bzip2" ]; then tar -xzf "$BASE_DIR/sources/bzip2-1.0.8.tar.gz" mv "bzip2-1.0.8" "$LFS_BUILD/bzip2" fi cd "$LFS_BUILD/bzip2" #make make CC="${CC}" AR="${AR}" RANLIB="${RANLIB}" -j 32 PREFIX=$LFS install if [ -f "$LFS/bin/bzip2" ]; then "$LFS_TGT-strip" --strip-unneeded "$LFS/bin/bzip2" else echo "Where is the bzip2 executable? It was there for bash 1.0.8!" exit 1 fi cd "$BASE_DIR" touch "$STEPS_DIR/bzip2" fi # build check if [ ! -f "$STEPS_DIR/check" ]; then if [ ! -d "$LFS_BUILD/check" ]; then tar -xzf "$BASE_DIR/sources/check-0.15.2.tar.gz" mv "check-0.15.2" "$LFS_BUILD/check" fi cd "$LFS_BUILD/check" mkdir -vp build cd build "../configure" \ --prefix=$LFS \ --host=${LFS_TGT} \ --libdir=$LFS/lib make -j 32 make -j 32 install cd "$BASE_DIR" touch "$STEPS_DIR/check" fi # build coreutils if [ ! -f "$STEPS_DIR/coreutils" ]; then if [ ! -d "$LFS_BUILD/coreutils" ]; then tar -xzf "$BASE_DIR/sources/coreutils-9.5.tar.gz" mv "coreutils-9.5" "$LFS_BUILD/coreutils" fi cd "$LFS_BUILD/coreutils" mkdir -vp build cd build "../configure" \ --prefix=$LFS \ --host=${LFS_TGT} \ --enable-install-program=hostname \ --cache-file=config.cache make -j 32 make -j 32 install cd "$BASE_DIR" touch "$STEPS_DIR/coreutils" fi # build diffutils if [ ! -f "$STEPS_DIR/diffutils" ]; then if [ ! -d "$LFS_BUILD/diffutils" ]; then tar -xf "$BASE_DIR/sources/diffutils-3.10.tar.xz" mv "diffutils-3.10" "$LFS_BUILD/diffutils" fi cd "$LFS_BUILD/diffutils" mkdir -vp build cd build "../configure" \ --prefix=$LFS \ --host=${LFS_TGT} \ --enable-install-program=hostname \ --cache-file=config.cache make -j 32 make -j 32 install cd "$BASE_DIR" touch "$STEPS_DIR/diffutils" fi #"$LFS_TGT-strip" --strip-unneeded $LFS/bin/* # build libcap2 #if [ ! -f "$STEPS_DIR/libcap2" ]; then # if [ ! -d "$LFS_BUILD/libcap2" ]; then # tar -xzf "$BASE_DIR/sources/libcap-2.73.tar.gz" # mv "libcap2" "$LFS_BUILD/libcap2" # fi # cd "$LFS_BUILD/libcap2" # # mkdir -vp build # cd build # # echo "rootsbindir=/usr/sbin" > configparms # # "../configure" \ # --prefix=/usr \ # --disable-static \ # --target=$LFS_TGT \ # --host=$(build-aux/config.guess) \ # --build=$(build-aux/config.guess) \ # # make -j 32 # make DESTDIR=$LFS install # # cd "$BASE_DIR" # # touch "$STEPS_DIR/libcap2" #fi # Remove man pages: totally useless rm -rf "$LFS"/usr/share/man rm -rf "$LFS"/man # Right now I have no idea if g++ will build crap.