diff --git a/README.md b/README.md index 7b74e54..ecd708a 100644 --- a/README.md +++ b/README.md @@ -1,127 +1,6 @@ # Maple Linux Bootstrap Scripts -This repository contains the scripts used to build Maple Linux from the source code. Most users will want to download a tarball from [here](https://maple.camp/linux/) to install Maple Linux. For everyone else, contributions are welcome! - -## System Requirements - -- Intel Core i3-6100 or greater -- At least 1 GB of storage space - -## Installing Maple Linux (For Most Users) - -Once you have a tarball downloaded from the repository above, you can begin installing Maple Linux. - -### Building the System Image - -First, you will need to start with a storage device that is around 4 GB in size (although, you can probably get away with less if you're brave). The first 512 MB should be an EFI System Partition (FAT32), and the remainder of the disk should be formatted as XFS. The following is an example of formatting the disk with `parted`, where `/dev/sdX` is the disk of your choice: - -``` -# parted /dev/sdX -GNU Parted 3.6 -Using /dev/sdX -Welcome to GNU Parted! Type 'help' to view a list of commands. -(parted) mklabel gpt -(parted) mkpart fat32 0% 512M -(parted) mkpart xfs 512M 100% -(parted) set 1 esp on -(parted) quit -``` - -That doesn't actually format the partitions, so we'll need to do that next: - -``` -# mkfs.fat -F32 /dev/sdX1 -mkfs.fat 4.2 (2021-01-31) -# mkfs.xfs /dev/sdX2 -meta-data=/dev/sdX2 isize=512 agcount=4, agsize=1017280 blks - = sectsz=512 attr=2, projid32bit=1 - = crc=1 finobt=1, sparse=1, rmapbt=1 - = reflink=1 bigtime=1 inobtcount=1 nrext64=1 - = exchange=0 metadir=0 -data = bsize=4096 blocks=4069120, imaxpct=25 - = sunit=0 swidth=0 blks -naming =version 2 bsize=4096 ascii-ci=0, ftype=1, parent=0 -log =internal log bsize=4096 blocks=19237, version=2 - = sectsz=512 sunit=0 blks, lazy-count=1 -realtime =none extsz=4096 blocks=0, rtextents=0 - = rgcount=0 rgsize=0 extents - = zoned=0 start=0 reserved=0 -Discarding blocks...Done. -``` - -Now that our image has been formatted correctly, we can extract the contents of Maple Linux to the disk. We'll start by creating a mount point for the root partition before mounting it and the boot partition. - -``` -# mkdir maple -# mount /dev/sdX2 maple -# mkdir maple/boot -# mount /dev/sdX1 maple/boot -``` - -Now that the image has been formatted properly, we can extract the contents of the tarball onto the system image: - -``` -# cd maple -# tar xf ../maplelinux-202507201645.tar.xz -``` - -### Configuring Limine - -To configure Limine, simply open `maple/boot/limine` in your text editor of choice. The only thing you *may* need to change is the value of `kernel_cmdline`. By default, it points to `/dev/vda2`, which is the default for a VirtIO disk on KVM. Of course, you can do [much more to customize your system](https://github.com/limine-bootloader/limine/blob/v9.x/CONFIG.md), but it is not required to boot. - -### Writing /etc/fstab - -Once again, you can change the fstab by opening `maple/etc/fstab` in your favorite text editor. The only two lines I would recommend changing are the first two unless you know what you're doing. The first line references the root partition and the second line references the boot partition. They are set to `/dev/vda2` and `/dev/vda1` respectively, as those are what KVM defaults to with a single VirtIO disk configured. This is what fstab should look like by default: - -``` -/dev/vda2 / xfs defaults 1 1 -/dev/vda1 /boot vfat defaults 0 2 -proc /proc proc nosuid,noexec,nodev 0 0 -sysfs /sys sysfs nosuid,noexec,nodev 0 0 -devpts /dev/pts devpts defaults 0 0 -tmpfs /run tmpfs defaults 0 0 -devtmpfs /dev devtmpfs mode=0755,nosuid 0 0 -tmpfs /dev/shm tmpfs nosuid,nodev 0 0 -cgroup2 /sys/fs/cgroup cgroup2 nosuid,noexec,nodev 0 0 -``` - -### Building initramfs - -Last, but certainly not least, is the initramfs. We'll start by creating the `maple/etc/tinyramfs` folder, which we'll use to store `maple/etc/tinyramfs/config`. Once again, `root` should be set to the root partition on your system. - -``` -root=/dev/vda2 -root_type=xfs -monolith=true -``` - -Once the initramfs builder has been configured, we can `chroot` into the image one final time, check the installed kernel version by listing the contents of `/lib/modules` (there should only be one subfolder), and invoking `tinyramfs` to build the initramfs for boot. - -``` -# chroot maple zsh -hostname# ls /lib/modules -6.15.4-maple -hostname# tinyramfs -k 6.15.4-maple /boot/initramfs ->> creating ramfs structure ->> generating initramfs image -+> done: /boot/initramfs -hostname# exit -``` - -With that, we can umount the image and boot into Maple Linux! - -## Building Maple Linux - -Building Maple Linux is mostly an automated process at this point. Here is a summary of the scripts provided in this repository, in order of execution (assuming nothing goes wrong): - -- `./fetch-sources.sh` - Downloads the sources and verifies their hashes against what is in `sources.list` -- `./build-bootstrap.sh` - Extracts and builds the bare minimum to build the remainder of the image in a `chroot` -- `./chroot-bootstrap.sh` - `chroot`s into the image with all the appropriate mounts -- `./build-chroot.sh` - Extracts and builds the system image from inside of the `chroot` - -This process has been known to take *hours*, so it's best not to do this unless you're sure you want to do it this way. Once you have a working bootstrap, it is recommended to back that up before proceeding with the chroot build so you can easily restore your progress without waiting for hours to get a new bootstrap. Of course, if you need to change LLVM for any reason, you will need to bootstrap the system again... - -Once you have a working image, you can follow the steps above to install the image normally. If you have any suggestions to improve the system or its build process, please make a pull request or issue! +This repository contains the scripts used to build Maple Linux from the source code. ## Maple Linux Philosophy diff --git a/STATUS.md b/STATUS.md index a9aac9a..d4df5bb 100644 --- a/STATUS.md +++ b/STATUS.md @@ -13,17 +13,17 @@ Definitions: | `bzip2` | Yes | Yes | | `chrony` | | `cmake` | Yes | Yes | -| `coreutils` | -| `dash` | +| `coreutils` | Yes | +| `dash` | Yes | | `dhcpcd` | -| `diffutils` | -| `findutils` | +| `diffutils` | Yes | +| `findutils` | Yes | | `flex` | Yes | Yes | | `fortune-mod` | | `gettext` | -| `grep` | +| `grep` | Yes | | `groff` | Yes | Yes | -| `gzip` | +| `gzip` | Yes | | `initramfs-tools` | Yes | Yes | | `iproute2` | | `kbd` | @@ -41,7 +41,7 @@ Definitions: | `llvm` | No | No | | `m4` | Yes | Yes | | `make` | Yes | Yes | -| `mawk` | +| `mawk` | Yes | | `muon` | Yes | Yes | | `musl` | Yes | Yes | | `nano` | @@ -49,12 +49,12 @@ Definitions: | `ncurses` | | `nftables` | | `openrc` | -| `patch` | +| `patch` | Yes | | `perl` | Yes | Yes | | `pkgconf` | Yes | Yes | -| `sed` | +| `sed` | Yes | | `shadow` | -| `tar` | +| `tar` | Yes | | `texinfo` | | `xlibre-xserver` | | `xz` | Yes | Yes | diff --git a/bootstrap.sh b/bootstrap.sh index 3c98326..50fdfcf 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,14 +1,14 @@ #!/bin/zsh -e -MICROARCH=skylake -TARGET=x86_64-maple-linux-musl +export MICROARCH=skylake +export 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 -SPEC=$(pwd)/sources +export ARCH=$(echo $TARGET | cut -d"-" -f1) +export BOOTSTRAP=$(pwd)/.bootstrap +export PROCS=$(nproc) +export SOURCES=$(pwd)/.treetap/sources +export SPEC=$(pwd)/sources export AR=llvm-ar export AS=llvm-as if [ ! -z "$CCACHE" ]; then @@ -35,8 +35,8 @@ $TREETAP fetch sources/llvm/llvm.spec $TREETAP fetch sources/musl/musl.spec # Make sure both clang-tblgen and llvm-tblgen are in the PATH. ~ahill -[ -z "$(which clang-tblgen)" ] && (echo "Unable to find clang-tblgen"; exit 1) -[ -z "$(which llvm-tblgen)" ] && (echo "Unable to find llvm-tblgen"; exit 1) +! which clang-tblgen && exit 1 +! which llvm-tblgen && exit 1 # Simplified filesystem heirarchy with symlinks for compatibility mkdir -p $BOOTSTRAP/root/{bin,boot/EFI/BOOT,dev,etc,home,lib,proc,run,sys,tmp,usr/{include,share},var/{cache,lib,log,spool,tmp}} @@ -219,12 +219,12 @@ cmake --build build-llvm --parallel $PROCS cmake --install build-llvm --parallel $PROCS # NOTE: LLVM doesn't add symlinks for clang, so we'll make them ourselves. # ~ahill -ln -s clang $BOOTSTRAP/root/bin/cc -ln -s clang++ $BOOTSTRAP/root/bin/c++ +ln -sf clang $BOOTSTRAP/root/bin/cc +ln -sf clang++ $BOOTSTRAP/root/bin/c++ cd .. # Build remaining software with treetap -SOURCES=(coreutils dash grep findutils gzip make mawk sed tar xz) +SOURCES=(coreutils dash diffutils findutils grep gzip make mawk patch sed tar) for name in $SOURCES; do $TREETAP fetch $SPEC/$name/$name.spec $TREETAP build $SPEC/$name/$name.spec @@ -247,6 +247,7 @@ SOURCES=( cmake coreutils dash + diffutils findutils flex grep @@ -264,6 +265,7 @@ SOURCES=( muon musl nasm + patch perl pkgconf sed diff --git a/rescue.sh b/rescue.sh new file mode 100755 index 0000000..1649d40 --- /dev/null +++ b/rescue.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# This file is made with lines from bootstrap.sh to create a shell in case the +# bootstrap fails to build for whatever reason. Building a sysroot, especially +# with LLVM, takes a stupid amount of time and it makes it unreasonable to +# rebuild after something like diffutils fails to build. ~ahill + +# The following script was created with: +# sh -c "grep export bootstrap.sh | sed /CCACHE/d; echo zsh" >> rescue.sh + +export MICROARCH=skylake +export TARGET=x86_64-maple-linux-musl +export ARCH=$(echo $TARGET | cut -d"-" -f1) +export BOOTSTRAP=$(pwd)/.bootstrap +export PROCS=$(nproc) +export SOURCES=$(pwd)/.treetap/sources +export SPEC=$(pwd)/sources +export AR=llvm-ar +export AS=llvm-as + export CC=clang + export CXX=clang++ +export CFLAGS="-fuse-ld=lld -O3 -march=$MICROARCH -pipe --sysroot=$BOOTSTRAP/root -Wno-unused-command-line-argument" +export CXXFLAGS=$CFLAGS +export RANLIB=llvm-ranlib +export LD=ld.lld +export LDFLAGS="--sysroot=$BOOTSTRAP/root" +export TREETAP=$(pwd)/treetap +export TT_DIR=$(pwd)/.treetap +export TT_MICROARCH=$MICROARCH +export TT_SYSROOT=$BOOTSTRAP/root +export TT_TARGET=$TARGET +export CFLAGS="$CFLAGS -Qunused-arguments -rtlib=compiler-rt -Wl,--dynamic-linker=/lib/ld-musl-$ARCH.so.1" +export CXXFLAGS="$CXXFLAGS -Qunused-arguments -rtlib=compiler-rt -Wl,--dynamic-linker=/lib/ld-musl-$ARCH.so.1" +export CFLAGS="$CFLAGS -unwindlib=libunwind" +export CXXFLAGS="$CXXFLAGS -isystem $BOOTSTRAP/root/usr/include/c++/v1 -nostdinc++ -stdlib=libc++ -unwindlib=libunwind" +export TT_DIR=$BOOTSTRAP/root/maple/.treetap +zsh diff --git a/rootbuild.sh b/rootbuild.sh index 6bf40a0..3143403 100755 --- a/rootbuild.sh +++ b/rootbuild.sh @@ -33,8 +33,13 @@ echo "Done!" # NOTE: automake requires m4 to build. ~ahill # NOTE: groff requires Perl to build. ~ahill # NOTE: nasm requires autoconf and automake to build. ~ahill +# NOTE: dash requires flex and mawk to build. ~ahill +# NOTE: libelf requires zlib to build. ~ahill cd /maple -PACKAGES="byacc bzip2 coreutils dash findutils grep gzip libelf libressl m4 make mawk muon musl perl pkgconf sed tar xz zlib autoconf automake flex groff libarchive libtool nasm cmake" +LAYER0="byacc bzip2 coreutils diffutils findutils grep gzip libressl m4 make mawk muon musl patch perl pkgconf sed tar xz zlib" +LAYER1="autoconf automake flex groff libarchive libelf libtool" +LAYER2="dash nasm cmake" +PACKAGES="$LAYER0 $LAYER1 $LAYER2" for pkg in $PACKAGES; do treetap fetch /maple/sources/$pkg/$pkg.spec treetap build /maple/sources/$pkg/$pkg.spec diff --git a/sources/diffutils/diffutils.spec b/sources/diffutils/diffutils.spec new file mode 100644 index 0000000..28eb121 --- /dev/null +++ b/sources/diffutils/diffutils.spec @@ -0,0 +1,23 @@ +# Maintainer: Alexander Hill +SRC_HASH="7c8b7f9fc8609141fdea9cece85249d308624391ff61dedaf528fcb337727dfd" +SRC_NAME="diffutils" +SRC_URL="https://ftp.gnu.org/gnu/diffutils/diffutils-3.12.tar.xz" +SRC_VERSION="3.12" + +build() { + tar xf ../$SRC_FILENAME + cd diffutils-$SRC_VERSION/ + # NOTE: GNU Diffutils 3.12 has a bug when cross-compiling, stating that it + # can't run a test because it is cross-compiling. Rather than ignore + # the issue, the configure script simply dies, preventing the build + # from proceeding. Adding gl_cv_func_strcasecmp_works fixes the issue + # without the need for a patch. ~ahill + # See also: https://lists.gnu.org/archive/html/bug-gnulib/2025-04/msg00056.html + ./configure $TT_AUTOCONF_COMMON gl_cv_func_strcasecmp_works=y + make -j $TT_PROCS +} + +package() { + cd diffutils-$SRC_VERSION/ + make -j $TT_PROCS install DESTDIR=$TT_INSTALLDIR +} \ No newline at end of file diff --git a/sources/linux/linux.spec b/sources/linux/linux.spec index d6ac1bd..27887bd 100755 --- a/sources/linux/linux.spec +++ b/sources/linux/linux.spec @@ -1,8 +1,8 @@ # Maintainer: Alexander Hill -SRC_HASH="7a8879167b89c4bae077d6f39c4f2130769f05dbdad2aad914adab9afb7d7f9a" +SRC_HASH="f850139ca5f79c1bf6bb8b32f92e212aadca97bdaef8a83a7cf4ac4d6a525fab" SRC_NAME="linux" -SRC_URL="https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.3.tar.xz" -SRC_VERSION="6.18.3" +SRC_URL="https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.4.tar.xz" +SRC_VERSION="6.18.4" build() { tar xf ../$SRC_FILENAME diff --git a/sources/mawk/mawk.spec b/sources/mawk/mawk.spec index ae0ab09..043512b 100644 --- a/sources/mawk/mawk.spec +++ b/sources/mawk/mawk.spec @@ -1,6 +1,7 @@ # Maintainer: Alexander Hill SRC_HASH="51bcb82d577b141d896d9d9c3077d7aaa209490132e9f2b9573ba8511b3835be" SRC_NAME="mawk" +SRC_REVISION=1 SRC_URL="https://invisible-island.net/archives/mawk/mawk-1.3.4-20250131.tgz" SRC_VERSION="1.3.4-20250131" @@ -14,4 +15,5 @@ build() { package() { cd mawk-$SRC_VERSION/ make -O -j $TT_PROCS install DESTDIR=$TT_INSTALLDIR + ln -s mawk $TT_INSTALLDIR/bin/awk } \ No newline at end of file diff --git a/sources/patch/patch.spec b/sources/patch/patch.spec new file mode 100644 index 0000000..aac3192 --- /dev/null +++ b/sources/patch/patch.spec @@ -0,0 +1,17 @@ +# Maintainer: Alexander Hill +SRC_HASH="f87cee69eec2b4fcbf60a396b030ad6aa3415f192aa5f7ee84cad5e11f7f5ae3" +SRC_NAME="patch" +SRC_URL="https://ftp.gnu.org/gnu/patch/patch-2.8.tar.xz" +SRC_VERSION="2.8" + +build() { + tar xf ../$SRC_FILENAME + cd patch-$SRC_VERSION/ + ./configure $TT_AUTOCONF_COMMON + make -j $TT_PROCS +} + +package() { + cd patch-$SRC_VERSION/ + make -j $TT_PROCS install DESTDIR=$TT_INSTALLDIR +} \ No newline at end of file diff --git a/sources/zlib/zlib.spec b/sources/zlib/zlib.spec index 497775a..0a06773 100644 --- a/sources/zlib/zlib.spec +++ b/sources/zlib/zlib.spec @@ -1,14 +1,22 @@ # Maintainer: Alexander Hill SRC_HASH="38ef96b8dfe510d42707d9c781877914792541133e1870841463bfa73f883e32" SRC_NAME="zlib" +SRC_REVISION=1 SRC_URL="https://www.zlib.net/zlib-1.3.1.tar.xz" SRC_VERSION="1.3.1" build() { tar xf ../$SRC_FILENAME - cd zlib-*/ + cd zlib-$SRC_VERSION/ # NOTE: The prefix is set to /usr because man pages are stored under the # prefix whether you like it or not. ~ahill + # NOTE: Zlib refuses to build a shared library if it can't pass the test. + # Rather than stopping the build, it simply proceeds to build a static + # library, which causes issues when building libarchive. The test is + # failing due to it relying on undefined symbols that are referenced + # in the linker script, which LLVM doesn't like at all. To tell LLVM + # to ignore it, we pass --undefined-version to the linker. ~ahill + CFLAGS="-Wl,--undefined-version $CFLAGS" \ ./configure \ --eprefix=$TT_PREFIX \ --includedir=$TT_INCLUDEDIR \ @@ -18,11 +26,7 @@ build() { make -O -j $TT_PROCS } -clean() { - rm -rf zlib-*/ -} - package() { - cd zlib-*/ + cd zlib-$SRC_VERSION/ make -O -j $TT_PROCS install DESTDIR=$TT_INSTALLDIR } \ No newline at end of file