Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ tools/*.out
tools/git_scraper
tools/custom_monitor
tools/compiler
tools/tools

# Ignore the output from the git scraper
src/git_info.h
Expand Down
61 changes: 0 additions & 61 deletions tools/install_arduino.sh

This file was deleted.

184 changes: 137 additions & 47 deletions tools/install_compiler.sh
Original file line number Diff line number Diff line change
@@ -1,52 +1,142 @@
# download links for gcc-arm-none-eabi-14.2.rel1
x86_64_Linux="https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz"
AArch64_Linux="https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-aarch64-arm-none-eabi.tar.xz"
x86_64_MacOS="https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-darwin-x86_64-arm-none-eabi.tar.xz"
Arm64_MacOS="https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-darwin-arm64-arm-none-eabi.tar.xz"

# where to store the compiler
OUTPUT=./tools/compiler

TAR_NAME=./arm-gnu-toolchain-14.2.rel1.tar.xz

# remove the old compiler
rm -rf $OUTPUT

# create a directory to store the compiler
mkdir -p $OUTPUT

# install the correct compiler based on the OS and architecture
if [[ "$(uname -s)" == "Linux" ]]; then
if [[ $(uname -m) == "x86_64" ]]; then
wget $x86_64_Linux -O $TAR_NAME
elif [[ $(uname -m) == "aarch64" ]]; then
wget $AArch64_Linux -O $TAR_NAME
fi
elif [[ "$(uname -s)" == "Darwin" ]]; then
# If wget is not installed, install it using Homebrew
# Suppress output with >/dev/null and 2>&1 sends errors to /dev/null
if ! command -v wget >/dev/null 2>&1; then
echo "wget not found. Installing via Homebrew..."
# If homebrew is installed, use it
if command -v brew >/dev/null 2>&1; then
brew install wget
else
echo "Homebrew is not installed. Please install Homebrew first: https://brew.sh/"
exit 1
fi
fi
if [[ $(uname -m) == "x86_64" ]]; then
wget "$x86_64_MacOS" -O "$TAR_NAME"
elif [[ $(uname -m) == "arm64" ]]; then
wget "$Arm64_MacOS" -O "$TAR_NAME"
fi
#!/usr/bin/env bash
# install_compiler.sh
#
# Installs the gcc-arm-none-eabi toolchain into tools/compiler/arm-gnu-toolchain.
#
# The download is verified against a pinned SHA256 and only swapped into place
# once it has been extracted successfully, so a failed or interrupted run always
# leaves the previously installed toolchain untouched.

set -euo pipefail

# --- what to install -------------------------------------------------------
# To bump the toolchain, change VERSION and refresh the table below. Each row is
# "<uname -s> <uname -m> <asset slug> <sha256>". Arm publishes the checksums
# next to each tarball, e.g. <BASE_URL>/<asset>.tar.xz.sha256asc
VERSION="14.2.rel1"
BASE_URL="https://developer.arm.com/-/media/Files/downloads/gnu/${VERSION}/binrel"

# --- where to put it -------------------------------------------------------
# Derived from the script's own location so it works from any directory.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OUTPUT="$SCRIPT_DIR/compiler"
DEST="$OUTPUT/arm-gnu-toolchain"

# --- pick the right tarball for this machine -------------------------------
OS="$(uname -s)"
ARCH="$(uname -m)"

# A shell running under Rosetta reports x86_64 even on Apple Silicon, which
# would silently install the (much slower) translated Intel toolchain.
# TODO: remove this when apple ends support for Intel-based apps in macOS 28
if [[ "$OS" == "Darwin" && "$ARCH" == "x86_64" ]] &&
[[ "$(sysctl -n sysctl.proc_translated 2>/dev/null)" == "1" ]]; then
echo "[WARN] Running under Rosetta; installing the native arm64 toolchain instead."
ARCH="arm64"
fi

case "$OS $ARCH" in
"Linux x86_64")
SLUG="x86_64-arm-none-eabi"
SHA256="62a63b981fe391a9cbad7ef51b17e49aeaa3e7b0d029b36ca1e9c3b2a9b78823" ;;
"Linux aarch64")
SLUG="aarch64-arm-none-eabi"
SHA256="87330bab085dd8749d4ed0ad633674b9dc48b237b61069e3b481abd364d0a684" ;;
"Darwin x86_64")
SLUG="darwin-x86_64-arm-none-eabi"
SHA256="2d9e717dd4f7751d18936ae1365d25916534105ebcb7583039eff1092b824505" ;;
"Darwin arm64")
SLUG="darwin-arm64-arm-none-eabi"
SHA256="c7c78ffab9bebfce91d99d3c24da6bf4b81c01e16cf551eb2ff9f25b9e0a3818" ;;
*)
echo "[ERROR] Unsupported platform: $OS $ARCH" >&2
echo "Arm ships this toolchain for Linux (x86_64, aarch64) and macOS (x86_64, arm64) only." >&2
echo "Install it manually into $DEST" >&2
exit 1
;;
esac

ASSET="arm-gnu-toolchain-${VERSION}-${SLUG}.tar.xz"
URL="$BASE_URL/$ASSET"

# macOS ships shasum, most Linux distros ship sha256sum. Resolve it up front so
# a machine that has neither fails before downloading 128MB it cannot verify.
if command -v shasum >/dev/null 2>&1; then
SHA_CMD=(shasum -a 256)
elif command -v sha256sum >/dev/null 2>&1; then
SHA_CMD=(sha256sum)
else
echo "[ERROR] Neither shasum nor sha256sum is available; cannot verify the download." >&2
exit 1
fi

# --- staging area ----------------------------------------------------------
# Kept inside $OUTPUT (already gitignored, and on the same filesystem as $DEST
# so the final swap is a rename rather than a copy of ~1GB).
mkdir -p "$OUTPUT"
WORK="$(mktemp -d "$OUTPUT/.install.XXXXXX")"

# If anything below fails after the old toolchain has been moved aside, put it
# back before clearing the staging area.
cleanup() {
if [[ -d "$WORK/previous" && ! -e "$DEST" ]]; then
echo "Restoring the previous toolchain..." >&2
mv "$WORK/previous" "$DEST"
fi
rm -rf "$WORK"
}
trap cleanup EXIT

# --- download --------------------------------------------------------------
# -f so an HTTP error page is never written out as a "tarball", -C - so a retry
# resumes instead of restarting the transfer from zero.
echo "Downloading $ASSET ..."
if [[ -t 2 ]]; then
PROGRESS="--progress-bar" # interactive: one bar
else
PROGRESS="--silent" # piped/CI: no per-update spam, -S keeps errors
fi
curl -fL "$PROGRESS" --show-error --retry 3 --retry-delay 2 -C - -o "$WORK/$ASSET" "$URL"

# --- verify ----------------------------------------------------------------
echo "Verifying checksum..."
ACTUAL="$("${SHA_CMD[@]}" "$WORK/$ASSET" | awk '{print $1}')"
if [[ "$ACTUAL" != "$SHA256" ]]; then
echo "[ERROR] Checksum mismatch for $ASSET" >&2
echo " expected: $SHA256" >&2
echo " actual: $ACTUAL" >&2
echo "The download was corrupted or tampered with. Nothing was installed." >&2
exit 1
fi

# extract the compiler
# --- extract ---------------------------------------------------------------
echo "Extracting the compiler..."
tar -xf "$TAR_NAME" -C "$OUTPUT"
mv "$OUTPUT"/arm-gnu-toolchain* "$OUTPUT"/arm-gnu-toolchain
mkdir -p "$WORK/extract"
tar -xf "$WORK/$ASSET" -C "$WORK/extract"
rm -f "$WORK/$ASSET"

# remove the downloaded tar file
# The tarball should contain exactly one top-level directory.
shopt -s nullglob
EXTRACTED=("$WORK"/extract/*/)
shopt -u nullglob
if [[ ${#EXTRACTED[@]} -ne 1 ]]; then
echo "[ERROR] Expected one directory in $ASSET, found ${#EXTRACTED[@]}." >&2
exit 1
fi

# --- swap into place -------------------------------------------------------
# Only now is the old toolchain touched, and it is moved aside rather than
# deleted so the cleanup trap can put it back if this fails.
echo "Installing to $DEST ..."
if [[ -e "$DEST" ]]; then
mv "$DEST" "$WORK/previous"
fi
mv "${EXTRACTED[0]%/}" "$DEST"

# Discard the old toolchain now rather than leaving a multi-second delete
# running under the trap after the success message.
echo "Cleaning up..."
rm -f "$TAR_NAME"
trap - EXIT
rm -rf "$WORK"

echo "[OK] arm-none-eabi toolchain $VERSION installed at $DEST"
Loading
Loading