lfs/build.sh
2024-12-06 19:04:37 +01:00

279 lines
No EOL
7.3 KiB
Bash
Executable file

#!/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
export LFS_TGT="$ARCH-lfs-linux-gnu"
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 \
--disable-nls \
--enable-gprofng=no \
--disable-werror \
--enable-new-dtags \
--disable-multilib \
--enable-default-hash-style=gnu
make configure-host
make -j 32
make install
cd "$BASE_DIR"
rm -rf binutils-2.43
touch "$STEPS_DIR/binutils"
fi
# Build gcc
if [ ! -f "$STEPS_DIR/gcc" ]; then
if [ ! -d "$LFS_BUILD/gcc" ]; then
tar -xzf "$BASE_DIR/sources/gcc-14.2.0.tar.gz"
mv "gcc-14.2.0" "$LFS_BUILD/gcc"
fi
cd "$LFS_BUILD/gcc/"
tar -xf "$BASE_DIR/sources/mpfr-4.2.1.tar.xz"
mv -v mpfr-4.2.1 mpfr
tar -xf "$BASE_DIR/sources/gmp-6.3.0.tar.xz"
mv -v gmp-6.3.0 gmp
tar -xf "$BASE_DIR/sources/mpc-1.3.1.tar.gz"
mv -v mpc-1.3.1 mpc
# 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 \
--prefix=$LFS_TOOLS \
--with-glibc-version=2.40 \
--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 \
--disable-decimal-float \
--disable-multilib \
--enable-languages=c,c++
make -j 32 # if build fails add --disable-libsanitizer
make 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"
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
LD="$LFS_TGT-ld" CC="$LFS_TGT-gcc" CXX="$LFS_TGT-g++" AR="$LFS_TGT-ar" RANLIB="$LFS_TGT-ranlib" 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 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
"../configure" \
--prefix=/usr \
--host=$LFS_TGT \
--build=$(../scripts/config.guess) \
--enable-kernel=4.19 \
--with-headers=$LFS/usr/include \
--disable-debug \
--without-selinux \
--disable-nscd \
libc_cv_slibdir=/usr/lib
make -j 32
make DESTDIR=$LFS install
sed '/RTLDLIST=/s@/usr@@g' -i $LFS/usr/bin/ldd
cd "$BASE_DIR"
rm -rf "$LFS_BUILD/glibc"
touch "$STEPS_DIR/glibc"
fi
# 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
# build libstdc++
if [ ! -f "$STEPS_DIR/libstdcxx" ]; then
bash unpack-gcc.sh
cd "$LFS_BUILD/gcc"
mkdir -vp build_libstdcxx
cd build_libstdcxx
#PATH="$PATH:$LFS_TOOLS/bin" RANLIB="$LFS_TOOLS/bin/$LFS_TGT-ranlib" AR="$LFS_TOOLS/bin/$LFS_TGT-ar" LD="$LFS_TOOLS/bin/$LFS_TGT-ld" CC="$LFS_TOOLS/bin/$LFS_TGT-gcc" CXX="$LFS_TOOLS/bin/$LFS_TGT-g++"
bash \
../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++/14.2.0
make -j 32
make DESTDIR=$LFS install
# Remove the libtool archive files because they are harmful for cross-compilation
rm -v $LFS/usr/lib/lib{stdc++{,exp,fs},supc++}.la
cd "$BASE_DIR"
rm -rf "$LFS_BUILD/gcc"
touch "$STEPS_DIR/libstdcxx"
fi
# 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 \
--build=$(build-aux/config.guess) \
make -j 32
make DESTDIR=$LFS install
cd "$BASE_DIR"
rm -rf "$LFS_BUILD/m4"
touch "$STEPS_DIR/m4"
fi