undroidwish-arm64-batteries-included

undroidwish for Apple Silicon (arm64)

Download (ready to run): a signed, Apple-notarized arm64 .dmg is published on GitHub Releases — no build required.

Get the latest at https://github.com/johnbuckman/undroidwish-arm64-batteries-included/releases/latest

Because it is notarized it opens without Gatekeeper warnings: just drag out the app and run.


Prefer to build it yourself? Read on.

A recipe — a small set of patches plus documentation — to build AndroWish's undroidwish (the batteries-included, single-file SDL2 wish) as a native Apple Silicon (arm64) macOS binary, instead of the stock x86-64 build that runs under Rosetta. It does not redistribute the AndroWish source: you clone AndroWish, apply the patches, and run its build script. The recipe, patches, and full documentation live at https://github.com/johnbuckman/undroidwish-arm64-batteries-included

The result is a self-contained wish with ~60 statically-linked Tcl/Tk extensions (Img, tls, tdom, BLT, tkpath, itk, tktreectrl, snack, mpexpr, …) running natively on arm64. Verified: native tclsh8.6/wish report arm64, and the Tcl regression suite passes (46090 tests, 1 environment-only failure).

Why bother — Rosetta 2 is going away

Apple is retiring Rosetta 2, the translation layer that lets x86-64 binaries run on Apple Silicon. At WWDC 2025 Apple said Rosetta would remain only "for the next two major macOS releases — through macOS 27"; macOS 26.4 (February 2026) already warns when you launch an Intel-only app, and macOS 28 (expected fall 2027) removes it. A stock x86-64 undroidwish runs on Apple Silicon only through Rosetta — so once Rosetta is gone, so is the stock build. A native arm64 binary is how AndroWish/Tk apps (for example de1app) keep running on the Mac.

Benchmarks — arm64 native vs x86 under Rosetta 2

Median of 5 runs on an M4 MacBook Air (macOS 26), geometric means, higher is faster:

  • Overall micro-benchmarks: 1.46× (~46% faster)
  • General Tcl — string/list/dict/regexp/array/binary: 1.53× (~53% faster)
  • Math — int/float/trig/fib: 1.47× (~47% faster)
  • Tk — widgets/canvas/text: 1.31× (~31% faster)
  • Startup — launch → ready: 1.25× (~20% faster)

So dropping Rosetta buys roughly 1.5× on compute and 1.25× on cold startup, on top of surviving the macOS 27/28 cutoff. Two honest caveats: the two builds also differ by a Tcl minor bump (8.6.9 → 8.6.10), so this is a real-world build-to-build comparison rather than pure arch isolation; and the Tk gains are the smallest because much of that work is SDL surface blitting on the GPU, which instruction-set translation does not touch — so pure-CPU work (math, lists) shows the biggest native win.

The core fix

Building undroidwish for arm64 surfaces a chain of issues, the central one being that AndroWish's SDL2 configure treats the Apple-Silicon Mac (host triple arm64-apple-darwin…) as iOS — enabling UIKit/OpenGL ES and disabling Cocoa — because its iOS branch label arm*-apple-darwin* swallows arm64 Macs. The patch set makes the arm64 Mac hit the macOS/Cocoa branch instead; the rest are modern-clang strictness, ancient-autoconf probes, x86-only SIMD paths, and a couple of bundled-library codec gaps. All are documented and patched in the repo.

The borg command on macOS

Stock undroidwish is "AndroWish sans the borg" — the Android borg command (a JNI bridge to the Android framework) is not compiled in, so code written for AndroWish that calls borg … fails with invalid command name "borg". This build adds jni/src/tkBorgOSX.c, a self-contained macOS reimplementation built as a loadable Tcl stubs package (package require Borg) and bundled into the embedded assets.zip. Its subcommand surface matches the documented Android command exactly, and it never raises a Tcl error on a well-formed call: where a macOS facility maps it does the real thing (say, open, IOKit, CoreGraphics, a typed preferences store), and where there is no analogue (NFC, telephony, Android content providers/intents) it is a safe no-op returning the Android-shaped empty value.

package require borg
borg speak "Shot ready"
borg toast "Saved"
set bi [borg osbuildinfo]   ;# manufacturer Apple, model Mac16,12, cpu_abi arm64

Bluetooth LE

The build also bundles a native macOS BLE driver that exposes the same ble command set as AndroWish on Android — scan, connect, discover services and characteristics, read, write, subscribe — driven by CoreBluetooth and marshalled onto the Tcl event loop. Code written against the Android ble command runs unchanged on the Mac desktop; the same package drives a Decent DE1 espresso machine and a BLE scale in real time.

Demos menu in the console

Launched bare — double-clicked, or undroidwish with no arguments — the arm64 build adds a File → Demos submenu to the Tk console. It gathers a small borg bridge demo and a Bluetooth-LE debugger alongside the bundled AndroWish demos (widget tour, tkcon, tkinspect, tksqlite, …); entries whose package is not bundled are greyed out. Launching with a script argument (undroidwish myapp.tcl) is unaffected — the menu only appears on a bare console launch.


See also

License: the patches, scripts, and documentation are under the Tcl/Tk license; AndroWish and the third-party libraries it bundles retain their own original licenses.

Contributed by John Buckman, 2026.

https://decentespresso.com/img/undroidwish-arm64-batteries-included.jpg