mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 03:37:45 +00:00
Toolchain: Add LLVM patch and script for building it
This contains all the bits and pieces necessary to build a Clang binary that will correctly compile SerenityOS. I had some trouble with getting LLVM building with a single command, so for now, I decided to build each LLVM component in a separate command invocation. In the future, we can also make the main llvm build step architecture-independent, but that would come with extra work to make library and include paths work. The binutils build invocation and related boilerplate is duplicated because we only use `objdump` from GNU binutils in the Clang toolchain, so most features can be disabled.
This commit is contained in:
parent
5d617be462
commit
15e217ea68
4 changed files with 1299 additions and 1 deletions
353
Toolchain/BuildClang.sh
Executable file
353
Toolchain/BuildClang.sh
Executable file
|
@ -0,0 +1,353 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
# === CONFIGURATION AND SETUP ===
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
echo "$DIR"
|
||||
|
||||
ARCH=${ARCH:-"i686"}
|
||||
LLVM_ARCH=
|
||||
[ "$ARCH" = "i686" ] && LLVM_ARCH="i386" || LLVM_ARCH="$ARCH"
|
||||
LLVM_TARGET="$LLVM_ARCH-pc-serenity"
|
||||
PREFIX="$DIR/Local/clang/$ARCH"
|
||||
BUILD="$DIR/../Build/$ARCH"
|
||||
SYSROOT="$BUILD/Root"
|
||||
|
||||
MD5SUM="md5sum"
|
||||
REALPATH="realpath"
|
||||
MAKE="make"
|
||||
NPROC="nproc"
|
||||
|
||||
SYSTEM_NAME="$(uname -s)"
|
||||
|
||||
if [ "$SYSTEM_NAME" = "OpenBSD" ]; then
|
||||
MD5SUM="md5 -q"
|
||||
REALPATH="readlink -f"
|
||||
MAKE="gmake"
|
||||
NPROC="sysctl -n hw.ncpuonline"
|
||||
export CC=egcc
|
||||
export CXX=eg++
|
||||
export LDFLAGS=-Wl,-z,notext
|
||||
elif [ "$SYSTEM_NAME" = "FreeBSD" ]; then
|
||||
MD5SUM="md5 -q"
|
||||
MAKE="gmake"
|
||||
NPROC="sysctl -n hw.ncpu"
|
||||
fi
|
||||
|
||||
if [ -z "$MAKEJOBS" ]; then
|
||||
MAKEJOBS=$($NPROC)
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d "$BUILD" ]; then
|
||||
mkdir -p "$BUILD"
|
||||
fi
|
||||
BUILD=$($REALPATH "$BUILD")
|
||||
|
||||
dev=
|
||||
while [ "$1" != "" ]; do
|
||||
case $1 in
|
||||
--dev ) dev=1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
echo PREFIX is "$PREFIX"
|
||||
echo SYSROOT is "$SYSROOT"
|
||||
|
||||
mkdir -p "$DIR/Tarballs"
|
||||
|
||||
LLVM_VERSION="12.0.1"
|
||||
LLVM_MD5SUM="c28061313a4f1b7d74cd491a19f569b4"
|
||||
LLVM_NAME="llvm-project-$LLVM_VERSION.src"
|
||||
LLVM_PKG="$LLVM_NAME.tar.xz"
|
||||
LLVM_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_PKG"
|
||||
|
||||
# We need GNU binutils because we use a feature that llvm-objdump doesn't support yet.
|
||||
BINUTILS_VERSION="2.37"
|
||||
BINUTILS_MD5SUM="1e55743d73c100b7a0d67ffb32398cdb"
|
||||
BINUTILS_NAME="binutils-$BINUTILS_VERSION"
|
||||
BINUTILS_PKG="${BINUTILS_NAME}.tar.gz"
|
||||
BINUTILS_BASE_URL="https://ftp.gnu.org/gnu/binutils"
|
||||
|
||||
buildstep() {
|
||||
NAME=$1
|
||||
shift
|
||||
"$@" 2>&1 | sed $'s|^|\x1b[34m['"${NAME}"$']\x1b[39m |'
|
||||
}
|
||||
|
||||
# === DEPENDENCIES ===
|
||||
buildstep dependencies echo "Checking whether 'make' is available..."
|
||||
if ! command -v ${MAKE:-make} >/dev/null; then
|
||||
buildstep dependencies echo "Please make sure to install GNU Make (for the '${MAKE:-make}' tool)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
buildstep dependencies echo "Checking whether CMake is available..."
|
||||
if ! command -v cmake >/dev/null; then
|
||||
buildstep dependencies echo "Please make sure to install CMake."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
buildstep dependencies echo "Checking whether 'patch' is available..."
|
||||
if ! command -v patch >/dev/null; then
|
||||
buildstep dependencies echo "Please make sure to install GNU patch."
|
||||
fi
|
||||
|
||||
buildstep dependencies echo "Checking whether your C compiler works..."
|
||||
if ! ${CC:-cc} -o /dev/null -xc - >/dev/null <<'PROGRAM'
|
||||
int main() {}
|
||||
PROGRAM
|
||||
then
|
||||
buildstep dependencies echo "Please make sure to install a working C compiler."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
buildstep dependencies echo "Checking whether your C++ compiler works..."
|
||||
if ! ${CXX:-c++} -o /dev/null -xc - >/dev/null <<'PROGRAM'
|
||||
int main() {}
|
||||
PROGRAM
|
||||
then
|
||||
buildstep dependencies echo "Please make sure to install a working C++ compiler."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# === DOWNLOAD AND PATCH ===
|
||||
|
||||
pushd "$DIR/Tarballs"
|
||||
md5=""
|
||||
if [ -e "$LLVM_PKG" ]; then
|
||||
md5="$($MD5SUM ${LLVM_PKG} | cut -f1 -d' ')"
|
||||
echo "llvm md5='$md5'"
|
||||
fi
|
||||
|
||||
if [ "$md5" != "$LLVM_MD5SUM" ] ; then
|
||||
rm -f "$LLVM_PKG"
|
||||
curl -LO "$LLVM_URL"
|
||||
else
|
||||
echo "Skipped downloading LLVM"
|
||||
fi
|
||||
|
||||
if [ -d "$LLVM_NAME" ]; then
|
||||
# Drop the previously patched extracted dir
|
||||
rm -rf "${LLVM_NAME}"
|
||||
# Also drop the build dir
|
||||
rm -rf "$DIR/Build/clang/$ARCH"
|
||||
fi
|
||||
echo "Extracting LLVM..."
|
||||
tar -xJf "$LLVM_PKG"
|
||||
|
||||
pushd "$LLVM_NAME"
|
||||
if [ "$dev" = "1" ]; then
|
||||
git init > /dev/null
|
||||
git add . > /dev/null
|
||||
git commit -am "BASE" > /dev/null
|
||||
git apply "$DIR"/Patches/llvm.patch > /dev/null
|
||||
else
|
||||
patch -p1 < "$DIR/Patches/llvm.patch" > /dev/null
|
||||
fi
|
||||
$MD5SUM "$DIR/Patches/llvm.patch" > .patch.applied
|
||||
popd
|
||||
|
||||
md5=""
|
||||
if [ -e "$BINUTILS_PKG" ]; then
|
||||
md5="$($MD5SUM $BINUTILS_PKG | cut -f1 -d' ')"
|
||||
echo "bu md5='$md5'"
|
||||
fi
|
||||
|
||||
if [ "$md5" != "$BINUTILS_MD5SUM" ]; then
|
||||
rm -f "$BINUTILS_PKG"
|
||||
curl -LO "$BINUTILS_BASE_URL/$BINUTILS_PKG"
|
||||
else
|
||||
echo "Skipped downloading GNU binutils"
|
||||
fi
|
||||
|
||||
if [ -d "$BINUTILS_NAME" ]; then
|
||||
rm -rf "$BINUTILS_NAME"
|
||||
rm -rf "$DIR/Build/clang/$ARCH/binutils"
|
||||
fi
|
||||
echo "Extracting GNU binutils"
|
||||
|
||||
|
||||
tar -xzf "$BINUTILS_PKG"
|
||||
pushd "$BINUTILS_NAME"
|
||||
if [ "$dev" = "1" ]; then
|
||||
git init > /dev/null
|
||||
git add . > /dev/null
|
||||
git commit -am "BASE" > /dev/null
|
||||
git apply "$DIR"/Patches/binutils.patch > /dev/null
|
||||
else
|
||||
patch -p1 < "$DIR/Patches/binutils.patch" > /dev/null
|
||||
fi
|
||||
$MD5SUM "$DIR/Patches/binutils.patch" > .patch.applied
|
||||
popd
|
||||
popd
|
||||
|
||||
# === COPY SERENITYOS HEADERS ===
|
||||
|
||||
mkdir -p "$BUILD"
|
||||
pushd "$BUILD"
|
||||
mkdir -p Root/usr/include/
|
||||
SRC_ROOT=$($REALPATH "$DIR"/..)
|
||||
FILES=$(find "$SRC_ROOT"/Userland/Libraries/LibC "$SRC_ROOT"/Userland/Libraries/LibM "$SRC_ROOT"/Userland/Libraries/LibPthread "$SRC_ROOT"/Userland/Libraries/LibDl -name '*.h' -print)
|
||||
for header in $FILES; do
|
||||
target=$(echo "$header" | sed -e "s@$SRC_ROOT/Userland/Libraries/LibC@@" -e "s@$SRC_ROOT/Userland/Libraries/LibM@@" -e "s@$SRC_ROOT/Userland/Libraries/LibPthread@@" -e "s@$SRC_ROOT/Userland/Libraries/LibDl@@")
|
||||
buildstep "system_headers" install -D "$header" "Root/usr/include/$target"
|
||||
done
|
||||
unset SRC_ROOT
|
||||
popd
|
||||
|
||||
# === COMPILE AND INSTALL ===
|
||||
|
||||
rm -rf "$PREFIX"
|
||||
mkdir -p "$PREFIX"
|
||||
|
||||
mkdir -p "$DIR/Build/clang/$ARCH"
|
||||
|
||||
pushd "$DIR/Build/clang/$ARCH"
|
||||
|
||||
mkdir -p llvm
|
||||
pushd llvm
|
||||
buildstep "llvm+clang/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/llvm" \
|
||||
-G Ninja \
|
||||
-DCMAKE_BUILD_TYPE="MinSizeRel" \
|
||||
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
|
||||
-DLLVM_DEFAULT_TARGET_TRIPLE="$LLVM_TARGET" \
|
||||
-DLLVM_TARGETS_TO_BUILD=X86 \
|
||||
-DLLVM_ENABLE_BINDINGS=OFF \
|
||||
-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \
|
||||
-DLLVM_ENABLE_PROJECTS="clang;lld" \
|
||||
-DLLVM_INCLUDE_BENCHMARKS=OFF \
|
||||
-DLLVM_INCLUDE_TESTS=OFF \
|
||||
${dev:+"-DLLVM_CCACHE_BUILD=ON"} || exit 1
|
||||
|
||||
buildstep "llvm+clang/build" ninja -j "$MAKEJOBS" || exit 1
|
||||
buildstep "llvm+clang/install" ninja install || exit 1
|
||||
popd
|
||||
|
||||
LLVM_COMPILER_FLAGS="-target $LLVM_TARGET --sysroot $SYSROOT -ftls-model=initial-exec -ffreestanding -nostdlib -nostdlib++"
|
||||
|
||||
mkdir -p "compiler-rt"
|
||||
pushd compiler-rt
|
||||
buildstep "compiler-rt/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/compiler-rt" \
|
||||
-GNinja \
|
||||
-DCMAKE_SYSROOT="$SYSROOT" \
|
||||
-DCMAKE_INSTALL_PREFIX="$PREFIX/lib/clang/${LLVM_VERSION}" \
|
||||
-DCMAKE_BUILD_TYPE="Release" \
|
||||
-DCMAKE_AR="$PREFIX/bin/llvm-ar" \
|
||||
-DCMAKE_C_COMPILER="$PREFIX/bin/clang" \
|
||||
-DCMAKE_C_COMPILER_TARGET="$LLVM_TARGET" \
|
||||
-DCMAKE_C_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DCMAKE_CXX_COMPILER="$PREFIX/bin/clang++" \
|
||||
-DCMAKE_CXX_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DCMAKE_CXX_COMPILER_TARGET="$LLVM_TARGET" \
|
||||
-DCMAKE_ASM_COMPILER="$PREFIX/bin/clang" \
|
||||
-DCMAKE_ASM_COMPILER_TARGET="$LLVM_TARGET" \
|
||||
-DCMAKE_ASM_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DLLVM_CONFIG_PATH="$PREFIX/bin/llvm-config" \
|
||||
-DCOMPILER_RT_EXCLUDE_ATOMIC_BUILTIN=OFF \
|
||||
-DCOMPILER_RT_OS_DIR="serenity" \
|
||||
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
|
||||
-DCOMPILER_RT_BUILD_BUILTINS=ON \
|
||||
-DCOMPILER_RT_BUILD_CRT=ON \
|
||||
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
|
||||
-DCOMPILER_RT_BUILD_MEMPROF=OFF \
|
||||
-DCOMPILER_RT_BUILD_PROFILE=OFF \
|
||||
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
|
||||
-DCOMPILER_RT_BUILD_XRAY=OFF || exit 1
|
||||
|
||||
buildstep "compiler-rt/build" ninja -j "$MAKEJOBS" || exit 1
|
||||
buildstep "compiler-rt/install" ninja install || exit 1
|
||||
popd
|
||||
|
||||
mkdir -p libunwind
|
||||
pushd libunwind
|
||||
buildstep "libunwind/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/libunwind" \
|
||||
-GNinja \
|
||||
-DCMAKE_BUILD_TYPE="Release" \
|
||||
-DCMAKE_SYSROOT="$SYSROOT" \
|
||||
-DCMAKE_C_COMPILER="$PREFIX/bin/clang" \
|
||||
-DCMAKE_C_COMPILER_TARGET="$LLVM_TARGET" \
|
||||
-DCMAKE_C_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DCMAKE_CXX_COMPILER="$PREFIX/bin/clang++" \
|
||||
-DCMAKE_CXX_COMPILER_TARGET="$LLVM_TARGET" \
|
||||
-DCMAKE_CXX_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
|
||||
-DLLVM_CONFIG_PATH="$PREFIX/bin/llvm-config" \
|
||||
-DLIBUNWIND_TARGET_TRIPLE="$LLVM_TARGET" \
|
||||
-DLIBUNWIND_SYSROOT="$SYSROOT" || exit 1
|
||||
|
||||
buildstep "libunwind/build" ninja -j "$MAKEJOBS" || exit 1
|
||||
buildstep "libunwind/install" ninja install || exit 1
|
||||
popd
|
||||
|
||||
mkdir -p libcxxabi
|
||||
pushd libcxxabi
|
||||
buildstep "libcxxabi/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/libcxxabi" \
|
||||
-GNinja \
|
||||
-DCMAKE_BUILD_TYPE="Release" \
|
||||
-DCMAKE_SYSROOT="$SYSROOT" \
|
||||
-DCMAKE_C_COMPILER="$PREFIX/bin/clang" \
|
||||
-DCMAKE_C_COMPILER_TARGET="$LLVM_TARGET" \
|
||||
-DCMAKE_C_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DCMAKE_CXX_COMPILER="$PREFIX/bin/clang++" \
|
||||
-DCMAKE_CXX_COMPILER_TARGET="$LLVM_TARGET" \
|
||||
-DCMAKE_CXX_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
|
||||
-DLLVM_CONFIG_PATH="$PREFIX/bin/llvm-config" \
|
||||
-DLIBCXXABI_STANDALONE_BUILD=ON \
|
||||
-DLIBCXXABI_ENABLE_EXCEPTIONS=ON \
|
||||
-DLIBCXXABI_STANDALONE_BUILD=ON \
|
||||
-DLIBCXXABI_ENABLE_ASSERTIONS=OFF \
|
||||
-DLIBCXXABI_BAREMETAL=ON || exit 1
|
||||
|
||||
buildstep "libcxxabi/build" ninja -j "$MAKEJOBS" || exit 1
|
||||
buildstep "libcxxabi/install" ninja install || exit 1
|
||||
popd
|
||||
|
||||
mkdir -p libcxx
|
||||
pushd libcxx
|
||||
buildstep "libcxx/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/libcxx" \
|
||||
-G Ninja \
|
||||
-DCMAKE_BUILD_TYPE="Release" \
|
||||
-DCMAKE_BINARY_DIR="$PREFIX/usr" \
|
||||
-DCMAKE_SYSROOT="$SYSROOT" \
|
||||
-DCMAKE_C_COMPILER="$PREFIX/bin/clang" \
|
||||
-DCMAKE_C_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DCMAKE_CXX_COMPILER="$PREFIX/bin/clang++" \
|
||||
-DCMAKE_CXX_FLAGS="$LLVM_COMPILER_FLAGS" \
|
||||
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
|
||||
-DLLVM_CONFIG_PATH="$PREFIX/bin/llvm-config" \
|
||||
-DLLVM_BINARY_DIR="$PREFIX/usr" \
|
||||
-DLIBCXX_INSTALL_LIBRARY=ON \
|
||||
-DLIBCXX_ENABLE_LOCALIZATION=OFF \
|
||||
-DLIBCXX_ENABLE_FILESYSTEM=OFF \
|
||||
-DLIBCXX_INSTALL_HEADERS=ON \
|
||||
-DLIBCXX_ENABLE_SHARED=ON \
|
||||
-DLIBCXX_ENABLE_LOCALIZATION=OFF \
|
||||
-DLIBCXX_ENABLE_STATIC=ON \
|
||||
-DLIBCXX_CXX_ABI="libcxxabi" \
|
||||
-DLIBCXX_INCLUDE_BENCHMARKS=OFF || exit 1
|
||||
|
||||
buildstep "libcxx/build" ninja -j "$MAKEJOBS" || exit 1
|
||||
buildstep "libcxx/install" ninja install || exit 1
|
||||
buildstep "libcxx/install-headers" ninja install-cxx-headers || exit 1
|
||||
popd
|
||||
|
||||
mkdir -p binutils
|
||||
pushd binutils
|
||||
buildstep "binutils/configure" "$DIR/Tarballs/$BINUTILS_NAME/configure" --prefix="$PREFIX/binutils" \
|
||||
--target="$ARCH-pc-serenity" \
|
||||
--disable-nls \
|
||||
--disable-gas \
|
||||
--disable-gold \
|
||||
--disable-ld \
|
||||
--disable-gprof \
|
||||
--enable-shared || exit 1
|
||||
buildstep "binutils/build" "$MAKE" -j "$MAKEJOBS" || exit 1
|
||||
buildstep "binutils/install" "$MAKE" install || exit 1
|
||||
popd
|
||||
popd
|
Loading…
Add table
Add a link
Reference in a new issue