@@ -348,7 +348,14 @@ defmodule Emily.MixProject do
348348 "MLX_DIR" => dir ,
349349 "MLX_INCLUDE_DIR" => Path . join ( dir , "include" ) ,
350350 "MLX_LIB_DIR" => Path . join ( dir , "lib" ) ,
351- "FINE_INCLUDE_DIR" => Fine . include_dir ( )
351+ "FINE_INCLUDE_DIR" => Fine . include_dir ( ) ,
352+ # Compile + link the NIF at the same macOS floor the vendored libmlx.a
353+ # was built for (see `macos_deployment_target/0`). clang honours this
354+ # env var for both the object compiles and the final link, so the NIF
355+ # and the static MLX objects agree on `LC_BUILD_VERSION` — no `ld`
356+ # version-mismatch warnings — and the shipped .so declares a
357+ # deterministic minimum rather than inheriting the build host's OS.
358+ "MACOSX_DEPLOYMENT_TARGET" => macos_deployment_target ( )
352359 }
353360 end
354361
@@ -426,7 +433,31 @@ defmodule Emily.MixProject do
426433 end
427434
428435 defp mlx_install_dir ,
429- do: Path . join ( cache_dir ( ) , "mlx-#{ @ mlx_version } -#{ mlx_variant ( ) } " )
436+ do:
437+ Path . join (
438+ cache_dir ( ) ,
439+ "mlx-#{ @ mlx_version } -#{ mlx_variant ( ) } -min#{ macos_deployment_target ( ) } "
440+ )
441+
442+ # Minimum macOS each MLX variant targets, pinned explicitly rather than
443+ # inheriting the build host's OS version. Threaded into both halves of the
444+ # build — the MLX source build via `CMAKE_OSX_DEPLOYMENT_TARGET`
445+ # (see scripts/build-mlx.sh) and the NIF compile/link via
446+ # `MACOSX_DEPLOYMENT_TARGET` (see make_env/0) — and folded into the cache
447+ # dir name above so changing a floor can't silently reuse a stale MLX build.
448+ #
449+ # * aot — the older-macOS-compatible path (built on macOS 14 in CI).
450+ # MLX's own hard floor is 14.0.
451+ # * jit — 26.2: its NAX kernels and the JACCL backend are gated on macOS
452+ # SDK >= 26.2 (deps/mlx_src/CMakeLists.txt), and the macOS-26 libSystem
453+ # `_Float16` helpers (`__fmaxf16`/`__fminf16`) it links aren't present on
454+ # earlier releases, so it isn't portable below 26.2.
455+ defp macos_deployment_target do
456+ case mlx_variant ( ) do
457+ "jit" -> "26.2"
458+ _ -> "14.0"
459+ end
460+ end
430461
431462 defp arch_tag do
432463 case { :os . type ( ) , :erlang . system_info ( :system_architecture ) |> to_string ( ) } do
@@ -495,7 +526,7 @@ defmodule Emily.MixProject do
495526 :binary ,
496527 :exit_status ,
497528 :stderr_to_stdout ,
498- { :args , [ mlx_src , @ mlx_version , jit_flag , install_dir ] }
529+ { :args , [ mlx_src , @ mlx_version , jit_flag , install_dir , macos_deployment_target ( ) ] }
499530 ]
500531
501532 port = Port . open ( { :spawn_executable , String . to_charlist ( script ) } , port_opts )
0 commit comments