diff --git a/README.md b/README.md index ff0ff7d..2922424 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,9 @@ Additionally you will need a version of the [aarch64-none-elf](https://developer #### Any OS To install aarch64-none-elf on any os, download the correct release of `aarch64-none-elf` onto your computer, unpack it, then export the `bin` folder to path. +#### macOS +There is experimental support for macOS in the scripts/mac-experimental folder. The scripts in there are not guaranteed to work for all macOS users and has only been tested on an M4 Apple Silicon MacBook Air. + #### NixOS Run the following command diff --git a/scripts/mac-experimental/README.md b/scripts/mac-experimental/README.md new file mode 100644 index 0000000..2ebc7ff --- /dev/null +++ b/scripts/mac-experimental/README.md @@ -0,0 +1,47 @@ +# Experimental macOS build scripts + +This is the folder for experimental macOS build support on Apple Silicon (we do not plan to support x86_64 macOS). + +These scripts are not guaranteed to work and are not actively supported by the maintainer or other contributors. +If you do have any issues, please mention @IAmTheNerdNextDoor in GitHub Issues. + +### Dependencies +Regardless of stdlib, you will need: +- [Rustup](https://rustup.rs) (DO NOT install Rustup from Homebrew as you will incur conflicts. If you have Rustup installed from Homebrew, uninstall it and reinstall from the Rustup site.) +- [aarch64-none-elf](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads) +- [Homebrew](https://brew.sh) +- QEMU (`brew install qemu`) +- dosfstools (`brew install dosfstools`) + +If building for the GNU library: +- aarch64-unknown-linux-gnu (`brew tap messense/macos-cross-toolchains && brew install aarch64-unknown-linux-gnu`) + +If building for the Musl library: +- Zig (`brew install zig`) + +We use Zig to cross-compile to Linux musl on macOS. + +When it comes to Rust, you need the nightly toolchain. To install it, run: +`rustup default nightly` + +### Building +You can start building the initrd programs using this script: +`./scripts/mac-experimental/build-deps.sh` + +musl programs are built by default. + +If you want GNU program builds: +`stdlib=gnu ./scripts/mac-experimental/build-deps.sh` + +After building, you can make the initrd with: +`./scripts/mac-experimental/create-image.sh` + +The initrd should now be at `./moss.img`. + +You can then build and run moss with: +`cargo run --release` + +If you get an error about `aarch64-unknown-none-softfloat` during building, you need to install the target: +`rustup target install aarch64-unknown-none-softfloat` + +Have fun! diff --git a/scripts/mac-experimental/build-deps.sh b/scripts/mac-experimental/build-deps.sh new file mode 100755 index 0000000..90bcec2 --- /dev/null +++ b/scripts/mac-experimental/build-deps.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +base="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../.. && pwd )" + +mkdir -p "$base/build/bin" +rm -f "$base/build/bin"/* + +pushd "$base/build" &>/dev/null || exit 1 + +popd &>/dev/null || exit 1 + +build=${build:-$(ls $base/scripts/deps)} + +for script in "$base/scripts/mac-experimental/deps/"* +do + [ -e "$script" ] || continue # skip if no file exists + [ -x "$script" ] || continue # skip if not executable + + filename=$(basename "$script") + + if [[ "$filename" == _* ]] + then + echo "Skipping: $filename" + continue + fi + + # skip if not in build list + if ! grep -qw "$filename" <<< "$build"; + then + echo "Skipping: $filename" + continue + fi + + echo "Preparing: $filename" + + # make sure each script is run in the base directory + pushd "$base" &>/dev/null || exit 1 + bash "$script" + popd &>/dev/null || exit 1 +done diff --git a/scripts/mac-experimental/create-image.sh b/scripts/mac-experimental/create-image.sh new file mode 100755 index 0000000..5a396b2 --- /dev/null +++ b/scripts/mac-experimental/create-image.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +base="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../.. && pwd )" +pushd "$base" &>/dev/null || exit 1 + +img="$base/moss.img" +mount="$base/build/mount" + +mkdir -p "$mount" + +dd if=/dev/zero of="$img" bs=1M count=128 +mkfs.vfat -F 32 "$img" + +if ! mount | grep -q "$mount"; then + hdiutil attach -mountpoint "$mount" "$img" +fi + +mkdir -p "$mount/bin" +mkdir -p "$mount/dev" + +cp "$base/build/bin"/* "$mount/bin" + +mounted=$(mount | grep "on $mount " | awk '{print $1}') +if [ -n "$mounted" ]; then + hdiutil detach "$mounted" +fi +popd &>/dev/null || exit 1 diff --git a/scripts/mac-experimental/deps/bash b/scripts/mac-experimental/deps/bash new file mode 100755 index 0000000..843f2e6 --- /dev/null +++ b/scripts/mac-experimental/deps/bash @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail + +bash_repo="${bash_repo:-https://git.savannah.gnu.org/git/bash.git}" +bash_tag="${bash_tag:-bash-5.3}" +stdlib="${stdlib:-musl}" + +if [ "$stdlib" == "gnu" ]; then + COMPILER="aarch64-linux-gnu-gcc" +else + COMPILER="zig cc -target aarch64-linux-musl" +fi + +pushd "build" &>/dev/null || exit 1 + +if [ ! -d "bash" ]; then + git clone --depth 1 --branch "$bash_tag" "$bash_repo" "bash" +else + pushd "bash" &>/dev/null || exit 1 + git pull + popd &>/dev/null || exit 1 +fi + +pushd "bash" &>/dev/null || exit 1 +./configure --without-bash-malloc --enable-static-link --host="aarch64-linux-$stdlib" CC="$COMPILER" +make +mv bash ../bin/bash +popd &>/dev/null || exit 1 + +popd &>/dev/null || exit 1 diff --git a/scripts/mac-experimental/deps/busybox b/scripts/mac-experimental/deps/busybox new file mode 100755 index 0000000..f1fb9d2 --- /dev/null +++ b/scripts/mac-experimental/deps/busybox @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +# busybox -- I couldn't get this to build. I ended up restoring to a third-party static binary which isn't ideal but it get's things running. +pushd "build" &>/dev/null || exit 1 +wget https://github.com/shutingrz/busybox-static-binaries-fat/raw/refs/heads/main/busybox-aarch64-linux-gnu +chmod +x busybox-aarch64-linux-gnu +mv busybox-aarch64-linux-gnu bin/busybox + +popd &>/dev/null || exit 1 + +popd &>/dev/null || exit 1 \ No newline at end of file