Introduce experimental macOS build support

Tested on my M4 MacBook Air, builds fine.
This commit is contained in:
NerdNextDoor
2025-11-26 13:57:08 +00:00
committed by Matthew Leach
parent 910203e0c2
commit 0904a1994c
6 changed files with 161 additions and 0 deletions

View File

@@ -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

View File

@@ -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!

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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