ml-explore / ml-explore/mlx

CMake cannot build Metal kernels for iOS

Open
#3,915 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
C++
Stars
28.5k
Forks
2.3k
Avg merge
3d 8h
Merged PRs (30d)
62

Description

Summary

MLX supports Metal on iOS through mlx-swift, but CMake-based consumers cannot currently build an iOS-compatible mlx.metallib.

mlx-swift handles this through a dedicated Swift/Xcode integration: its Package.swift compiles the vendored MLX and MLX-C sources as the Cmlx target, while Xcode builds and bundles the Metal shaders separately. This path is not available to consumers that build MLX through CMake.

For example, bindings such as mlx-rs use the following dependency chain:

mlx-rs -> mlx-sys -> mlx-c -> mlx

Here, mlx-sys enables MLX_BUILD_METAL and invokes the MLX-C CMake build, so MLX is expected to generate its built-in Metal kernels.

Problem

PR #3617 fixed the configure-level issue that forced MLX_BUILD_METAL off when CMAKE_SYSTEM_NAME was iOS. However, the Metal kernel custom commands still explicitly use:

xcrun -sdk macosx metal ...
-mmacosx-version-min=...

The final mlx.metallib is also linked with the macOS SDK. These custom commands do not inherit CMAKE_OSX_SYSROOT=iphoneos or iphonesimulator, so callers still cannot produce an iOS-compatible Metal library through the normal CMake build.

Proof of concept

I implemented a reference fix in kadu-v/mlx@6d1f0185. It:

  • selects iphoneos, iphonesimulator, or macosx from the CMake target;
  • uses the matching iOS, Simulator, or macOS deployment-target flag;
  • probes the iOS Metal language version instead of always using the baseline feature set;
  • optionally exposes the existing SwiftPM bundle lookup for default.metallib.

With these changes, the same MLX CMake build can generate Metal kernels for macOS, iPhone devices, and the iOS Simulator without changing the existing macOS behavior.

Would upstream be open to target-aware SDK handling like this? Alternatively, is there an existing supported way for a CMake caller to override the SDK and deployment-target flag used by the Metal kernel custom commands?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the CMake Metal-kernel custom commands and the configure changes from PR #3617, then compare them with the linked proof-of-concept commit. Done means the normal CMake build selects the appropriate device, simulator, or macOS SDK and deployment target while preserving existing macOS behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
cmake, cpp
Domain
build-system, mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.