Downloads and caches pre-built Apple MLX + EMLX NIF static archives so
iOS Mob apps can ship EMLX.Backend as an Nx backend without
cross-compiling MLX themselves.
Mirrors the MobDev.OtpDownloader / MobDev.PythonAppleSupport pattern:
hashed URL + cached download at ~/.mob/cache/mlx-<version>-<target>/,
validated against the expected layout. Reused across projects.
Used by MobDev.NativeBuild when the project's deps include :emlx or
mob.exs declares mlx_enabled: true. The build template sources
MLX_DIR from dir/1 and links libmlx.a + libemlx.a from there.
Scope (v1)
CPU-only MLX. Metal-on-iOS is gated behind a separate tarball variant
(libmlx-<ver>-ios-device-metal.tar.gz) that requires the iOS-Metal
CMakeLists patch and the Xcode Metal Toolchain installed at build
time. v1 ships CPU + Accelerate framework — already
~10-50x faster than Nx.BinaryBackend for typical Nx workloads.
Local-build override
Set MOB_MLX_LOCAL_TARBALL_DIR=/path/to/dir to bypass the GitHub
download and use locally-built tarballs (named exactly as
tarball_name/1 returns). Useful when iterating on the cross-compile
scripts in mob_dev/scripts/release/mlx/.
Summary
Functions
Cached MLX root directory for target. May not exist if ensure/1
hasn't been called.
Download URL for the target tarball.
Ensure the MLX bundle for target is cached and extracted.
Returns {:ok, path} where path is the unpacked root containing
lib/libmlx.a, lib/libemlx.a, include/mlx/..., VERSION.
Convenience for iOS device.
Convenience for iOS simulator.
Path to mlx.metallib if this bundle ships Metal GPU kernels, or
nil if it's a CPU-only bundle.
Pinned MLX upstream version (e.g. 0.25.1).
Bundle name (no extension, no path) for target — libmlx-0.25.1-ios-device etc.
GitHub release tag this downloader targets.
Tarball file name for target (e.g. libmlx-0.25.1-ios-device.tar.gz).
Returns true if the cache directory has the expected layout
(lib/libmlx.a, lib/libemlx.a, include/mlx/, VERSION).
Types
Functions
Cached MLX root directory for target. May not exist if ensure/1
hasn't been called.
Download URL for the target tarball.
Ensure the MLX bundle for target is cached and extracted.
Returns {:ok, path} where path is the unpacked root containing
lib/libmlx.a, lib/libemlx.a, include/mlx/..., VERSION.
Convenience for iOS device.
Convenience for iOS simulator.
Path to mlx.metallib if this bundle ships Metal GPU kernels, or
nil if it's a CPU-only bundle.
The CPU build (scripts/release/mlx/ios_device.sh) doesn't produce
a metallib. The Metal build (ios_device_metal.sh) puts one at
lib/mlx.metallib alongside the static archives. Callers use this
to decide whether to copy the metallib into the iOS .app bundle so
EMLX's runtime device: :gpu path can find it (via MLX's
load_colocated_library).
@spec mlx_version() :: String.t()
Pinned MLX upstream version (e.g. 0.25.1).
Bundle name (no extension, no path) for target — libmlx-0.25.1-ios-device etc.
@spec release_tag() :: String.t()
GitHub release tag this downloader targets.
Tarball file name for target (e.g. libmlx-0.25.1-ios-device.tar.gz).
Returns true if the cache directory has the expected layout
(lib/libmlx.a, lib/libemlx.a, include/mlx/, VERSION).
Public for testing and so NativeBuild can cheaply probe for a partial
cache without parsing the VERSION file.