summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Hill <ahill@breadpudding.dev>2025-11-12 21:41:26 -0500
committerAlexander Hill <ahill@breadpudding.dev>2025-11-12 21:41:26 -0500
commit09f2e062cad929f867bb96c97ed581aa79df7c71 (patch)
treea83675d6ff43450a6d89e4bc425dcdfad9cec20f
parent8bd73c53fceec182c8e9908ac64cf25a05ddf45d (diff)
Successfully bootstrapped with LLVM 21!
This took a LOT longer than I would have liked, but I'm so happy that it's working again!
-rwxr-xr-xbootstrap.sh77
-rwxr-xr-x[-rw-r--r--]sources/busybox.spec0
-rwxr-xr-x[-rw-r--r--]sources/linux.spec0
-rwxr-xr-x[-rw-r--r--]sources/llvm.spec0
-rwxr-xr-x[-rw-r--r--]sources/musl.spec0
-rwxr-xr-xtreetap44
6 files changed, 88 insertions, 33 deletions
diff --git a/bootstrap.sh b/bootstrap.sh
index 36fc599..5db4386 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -1,10 +1,22 @@
#!/bin/zsh -e
-BOOTSTRAP=$(pwd)/.bootstrap
MICROARCH="skylake"
+TARGET=x86_64-maple-linux-musl
+
+# Set the environment up
+ARCH=$(echo $TARGET | cut -d"-" -f1)
+BOOTSTRAP=$(pwd)/.bootstrap
PROCS=$(nproc)
SOURCES=$(pwd)/.treetap/sources
-TARGET=x86_64-maple-linux-musl
+export AR=llvm-ar
+export CC=clang
+export CFLAGS="-fuse-ld=lld -O3 -march=$MICROARCH -pipe --sysroot=$BOOTSTRAP/root -Wno-unused-command-line-argument"
+export CXX=clang++
+export CXXFLAGS=$CFLAGS
+export RANLIB=llvm-ranlib
+export LD=ld.lld
+export TREETAP_SYSROOT=$BOOTSTRAP/root
+export TREETAP_TARGET=$TARGET
# Fetch sources required for a bootstrap
./treetap fetch sources/busybox.spec
@@ -23,16 +35,6 @@ ln -sf ../run/lock $BOOTSTRAP/root/var/lock
ln -sf ../run $BOOTSTRAP/root/var/run
# Prepare for the build
-ARCH=$(echo $TARGET | cut -d"-" -f1)
-export AR=llvm-ar
-export CC=clang
-export CFLAGS="-fuse-ld=lld -O3 -march=$MICROARCH -pipe --sysroot=$BOOTSTRAP/root -Wno-unused-command-line-argument"
-export CXX=clang++
-export CXXFLAGS=$CFLAGS
-export RANLIB=llvm-ranlib
-export LD=ld.lld
-export TREETAP_SYSROOT=$BOOTSTRAP/root
-export TREETAP_TARGET=$TARGET
mkdir -p $BOOTSTRAP/build
cd $BOOTSTRAP/build
@@ -82,7 +84,8 @@ cd musl-*/
--includedir=/usr/include \
--libdir=/lib \
--prefix=/
-make -O -j $PROCS
+# NOTE: The build is skipped here because we only care about the header files at
+# this point. ~ahill
make -O -j $PROCS install-headers DESTDIR=$BOOTSTRAP/root
cd ..
@@ -100,7 +103,7 @@ cd ..
# Build musl for real this time
cd musl-*/
-# TODO: CVE-2025-26519
+# FIXME: Patch CVE-2025-26519 ~ahill
make clean
# NOTE: LIBCC is required here because it will attempt to link with the build
# system's runtime if this is not specified. ~ahill
@@ -124,9 +127,13 @@ export CXXFLAGS="$CXXFLAGS -Qunused-arguments -rtlib=compiler-rt -Wl,--dynamic-l
# setting CMAKE_CXX_COMPILER_WORKS, therefore tricking CMake into
# performing a successful build. Yet another instance where the genie in
# the bottle does exactly what we asked, and not what we wanted. ~ahill
+# NOTE: Not sure why this didn't show up before, but CMAKE_C_COMPILER_WORKS is
+# is manually set because the C compiler attempts to link with libgcc_s or
+# libunwind, even though it doesn't exist yet. ~ahill
cd llvm-project-*/
cmake -S runtimes -B build-runtimes \
-DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_C_COMPILER_WORKS=ON \
-DCMAKE_CXX_COMPILER_WORKS=ON \
-DCMAKE_INSTALL_INCLUDEDIR=$BOOTSTRAP/root/usr/include \
-DCMAKE_INSTALL_PREFIX=$BOOTSTRAP/root \
@@ -143,21 +150,28 @@ cmake --build build-runtimes --parallel $PROCS
cmake --install build-runtimes --parallel $PROCS
cd ..
-# Now we can introduce libc++ into the environment
+# Now we can introduce libunwind and libc++ into the environment
# NOTE: clang++ attempts to build with headers from the build system rather than
# exclusively relying on the sysroot. Because of this, we must manually
# define the proper include path. ~ahill
-export CXXFLAGS="$CXXFLAGS -isystem $BOOTSTRAP/root/usr/include/c++/v1 -nostdinc++ -stdlib=libc++"
+export CFLAGS="$CFLAGS -unwindlib=libunwind"
+export CXXFLAGS="$CXXFLAGS -isystem $BOOTSTRAP/root/usr/include/c++/v1 -nostdinc++ -stdlib=libc++ -unwindlib=libunwind"
-# Build LLVM itself
+# Build clang/LLVM
# NOTE: LLVM_ENABLE_ZSTD is disabled because we don't have zstd in the sysroot,
# and because I don't believe that a library created by Facebook should
# be required for an operating system to function. ~ahill
+# NOTE: If we don't do this, LLVM attempts to build its own copy of tblgen,
+# which will cause the build to fail since we're cross-compiling and can't
+# run programs built for another platform. LLVM_NATIVE_TOOL_DIR,
+# LLVM_TABLEGEN, and CLANG_TABLEGEN are set based on this variable. ~ahill
+NATIVE_TOOL_DIR=$(dirname $(which llvm-tblgen))
cd llvm-project-*/
cmake -S llvm -B build-llvm \
-DCLANG_DEFAULT_CXX_STDLIB=libc++ \
-DCLANG_DEFAULT_RTLIB=compiler-rt \
-DCLANG_DEFAULT_UNWINDLIB=libunwind \
+ -DCLANG_TABLEGEN=$NATIVE_TOOL_DIR/clang-tblgen \
-DCLANG_VENDOR=Maple \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$BOOTSTRAP/root \
@@ -165,7 +179,32 @@ cmake -S llvm -B build-llvm \
-DLLVM_ENABLE_LIBCXX=ON \
-DLLVM_ENABLE_PROJECTS="clang;lld;llvm" \
-DLLVM_ENABLE_ZSTD=OFF \
- -DLLVM_HOST_TRIPLE=$TARGET
+ -DLLVM_HOST_TRIPLE=$TARGET \
+ -DLLVM_NATIVE_TOOL_DIR=$NATIVE_TOOL_DIR \
+ -DLLVM_TABLEGEN=$NATIVE_TOOL_DIR/llvm-tblgen
cmake --build build-llvm --parallel $PROCS
-# ...
+cmake --install build-llvm --parallel $PROCS
cd ..
+
+# Build Busybox
+tar xf $SOURCES/busybox/*/busybox-*.tar*
+cd busybox-*/
+# NOTE: Like we did with musl before, we don't set CROSS_COMPILE because LLVM is
+# smart and doesn't need a compiler to cross-compile code. With that said,
+# Busybox uses Kbuild, which hard-codes variables like CC to GNU-based
+# tools, which is not what we want. The following sed hack should do the
+# trick, but I wonder if there's a better solution. ~ahill
+sed -i "s/?*= \$(CROSS_COMPILE)/?= /" Makefile
+make -O -j $PROCS defconfig
+# NOTE: tc causes a LOT of issues due to undefined things. We don't really need
+# "traffic control" at this time, and when we eventually do, we will
+# likely use something else. ~ahill
+sed -i "s/CONFIG_TC=.*/CONFIG_TC=n/" .config
+make -O -j $PROCS
+# NOTE: Busybox doesn't appear to have a proper DESTDIR, so we just set
+# CONFIG_PREFIX during the install step to work around this. ~ahill
+make -O -j $PROCS install CONFIG_PREFIX=$BOOTSTRAP/root
+cd ..
+
+# Install Treetap
+cp $BOOTSTRAP/../treetap $BOOTSTRAP/root/bin/ \ No newline at end of file
diff --git a/sources/busybox.spec b/sources/busybox.spec
index b2fd1aa..b2fd1aa 100644..100755
--- a/sources/busybox.spec
+++ b/sources/busybox.spec
diff --git a/sources/linux.spec b/sources/linux.spec
index 7b8566f..7b8566f 100644..100755
--- a/sources/linux.spec
+++ b/sources/linux.spec
diff --git a/sources/llvm.spec b/sources/llvm.spec
index d1f076e..d1f076e 100644..100755
--- a/sources/llvm.spec
+++ b/sources/llvm.spec
diff --git a/sources/musl.spec b/sources/musl.spec
index 5811461..5811461 100644..100755
--- a/sources/musl.spec
+++ b/sources/musl.spec
diff --git a/treetap b/treetap
index d8287e5..1c83a3a 100755
--- a/treetap
+++ b/treetap
@@ -14,6 +14,16 @@
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
+#############
+# Changelog #
+#############
+
+# November 11, 2025 (1.0.1)
+# - Removed bashisms to become POSIX compliant
+
+# November 9, 2025 (1.0.0)
+# * Initial release
+
####################
# Global Variables #
####################
@@ -21,7 +31,7 @@
[ -z "$TREETAP_DIR" ] && TREETAP_DIR="$(pwd)/.treetap"
[ -z "$TREETAP_PKGDIR" ] && TREETAP_PKGDIR="$TREETAP_DIR/packages"
[ -z "$TREETAP_SYSROOT" ] && TREETAP_SYSROOT=/
-TREETAP_VERSION="1.0.0"
+TREETAP_VERSION="1.0.1"
#####################
# Utility Functions #
@@ -60,7 +70,7 @@ source_spec() {
[ ! -f "$1" ] && (echo "source_spec: Specification file \"$1\" not found"; exit 1)
# Zhu Li, do the thing!
- source $1
+ . $1
# Required Fields
[ -z "$SRC_HASH" ] && (echo "source_spec: SRC_HASH is required but not defined"; exit 1)
@@ -95,9 +105,10 @@ package_install() {
package_check $1 $TREETAP_SYSROOT
echo "Installing $(basename $1)"
FULLPATH=$(pwd)/$1
- pushd $TREETAP_SYSROOT > /dev/null
+ PUSHD=$(pwd)
+ cd $TREETAP_SYSROOT
xz -cd $FULLPATH | cpio -idmu --quiet
- popd > /dev/null
+ cd $PUSHD
exit 0
}
@@ -107,7 +118,8 @@ package_uninstall() {
package_check $1 $TREETAP_SYSROOT
echo "Uninstalling $(basename $1)"
FULLPATH=$(pwd)/$1
- pushd $TREETAP_SYSROOT > /dev/null
+ PUSHD=$(pwd)
+ cd $TREETAP_SYSROOT
xz -cd $FULLPATH | cpio -it --quiet | tail -n +2 | sort -r | while read path; do
if [ -d $path ]; then
rmdir --ignore-fail-on-non-empty $path
@@ -115,7 +127,7 @@ package_uninstall() {
rm -f $path
fi
done
- popd > /dev/null
+ cd $PUSHD
exit 0
}
@@ -123,10 +135,11 @@ package_uninstall() {
source_build() {
source_spec $1
mkdir -p $TREETAP_BUILDDIR
- pushd $TREETAP_BUILDDIR > /dev/null
+ PUSHD=$(pwd)
+ cd $TREETAP_BUILDDIR
echo "Building $SRC_NAME $SRC_VERSION"
build > build-$(date +%Y%m%d%H%M%S).log 2>&1
- popd > /dev/null
+ cd $PUSHD
exit 0
}
@@ -134,11 +147,12 @@ source_build() {
source_clean() {
source_spec $1
mkdir -p $TREETAP_BUILDDIR
- pushd $TREETAP_BUILDDIR > /dev/null
+ PUSHD=$(pwd)
+ cd $TREETAP_BUILDDIR
echo "Cleaning $SRC_NAME $SRC_VERSION"
clean
rm -rf $TREETAP_INSTALLDIR
- popd > /dev/null
+ cd $PUSHD
exit 0
}
@@ -146,12 +160,13 @@ source_clean() {
source_fetch() {
source_spec $1
mkdir -p $TREETAP_BUILDDIR
- pushd $TREETAP_BUILDDIR/.. > /dev/null
+ PUSHD=$(pwd)
+ cd $TREETAP_BUILDDIR/..
echo "Fetching $SRC_FILENAME"
curl -L -sS $SRC_URL -o $SRC_FILENAME
echo "Verifying $SRC_FILENAME"
echo "$SRC_HASH $SRC_FILENAME" | sha256sum -c - > /dev/null
- popd > /dev/null
+ cd $PUSHD
exit 0
}
@@ -161,14 +176,15 @@ source_package() {
mkdir -p $TREETAP_BUILDDIR
mkdir -p $TREETAP_INSTALLDIR
mkdir -p $TREETAP_PKGDIR
- pushd $TREETAP_BUILDDIR > /dev/null
+ PUSHD=$(pwd)
+ cd $TREETAP_BUILDDIR
echo "Moving artifacts for $SRC_NAME $SRC_VERSION"
package > package-$(date +%Y%m%d%H%M%S).log
echo "Archiving $SRC_NAME $SRC_VERSION"
cd $TREETAP_INSTALLDIR
find | cpio -o --quiet | xz -cz > "$TREETAP_PKGDIR/$SRC_NAME-$SRC_VERSION.cpio.xz"
rm -rf $TREETAP_INSTALLDIR
- popd > /dev/null
+ cd $PUSHD
exit 0
}