@@ -7,6 +7,95 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77
88<!-- %% CHANGELOG_ENTRIES %% -->
99
10+ ## 0.3.0 - 2026-04-25
11+
12+ ### Changed
13+
14+ - Hex consumers now receive a precompiled NIF
15+ (` libemily.{so,dylib} ` + ` mlx.metallib ` ) instead of source. First
16+ ` mix compile ` downloads the matching `emily-nif-<v >-<variant >-
17+ <target >.tar.gz` (and its ` .sha256` sidecar) from the emily GitHub
18+ release for the pinned version, verifies the tarball against the
19+ published SHA256, and extracts into ` priv/ ` . No cmake / Xcode /
20+ C++ toolchain is needed on the consumer side.
21+ - In-repo / CI builds now clone MLX's source via a Mix git dep
22+ (` :mlx_src ` ) and build libmlx from source; ` release-mlx.yml ` is
23+ retired.
24+ - Variant selection is unified under the ` :variant ` app-config key
25+ (` :aot ` | ` :jit ` ). Contributors flip variants via
26+ ` EMILY_MLX_VARIANT=jit ` (read by ` config/config.exs ` ); consumers
27+ set ` config :emily, variant: :jit ` in their own
28+ ` config/config.exs ` . The old ` :mlx_variant ` key and
29+ ` config/local.exs ` override are gone.
30+ - macOS default cache location moves from ` ~/Library/Caches/emily/ `
31+ to ` DARWIN_USER_CACHE_DIR ` (` /private/var/folders/<hash>/C/emily ` )
32+ — the per-user sandboxed cache root Apple's own sandboxed apps
33+ use. Persistent across reboots, lives outside ` ~/Library/ ` .
34+ Linux / Windows still use the XDG convention. Override via
35+ ` EMILY_CACHE ` . Existing macOS users can `rm -rf
36+ ~ /Library/Caches/emily/` to reclaim the orphaned data after
37+ upgrade.
38+ - NIF object files move from the user-level cache to
39+ ` $(MIX_APP_PATH)/obj/ ` (i.e. ` _build/<env>/lib/emily/obj/ ` ). As a
40+ consequence, plain ` mix clean ` now correctly removes them via the
41+ existing Makefile rule — they were previously left behind because
42+ ` make clean ` didn't see the cache-dir env vars.
43+
44+ ### Added
45+
46+ - ` .github/workflows/release-nif.yml ` — on bare-semver tag push,
47+ builds the precompiled NIF for each ` (variant × target) ` cell and
48+ uploads tarball + ` .sha256 ` sidecar to a draft GitHub release.
49+ ` workflow_dispatch ` is also wired for out-of-band rebuilds
50+ (artefacts go to workflow storage; the release is untouched).
51+ - ` mix clean.mlx ` — wipes the MLX install dir(s) under the cache.
52+ Plain ` mix clean ` deliberately preserves them since rebuilding
53+ MLX from source is ~ 5-7 minutes.
54+
55+ ### Fixed
56+
57+ - MLX source builds are now atomic. The build script installs into
58+ ` ${PREFIX}.staging ` and only ` mv ` s onto the final path after the
59+ artefact sanity checks pass; an EXIT trap wipes the scratch dirs
60+ on failure. Previously, an interrupted build (Ctrl-C, killed
61+ process, concurrent run) left an empty install dir that
62+ subsequent ` mix compile ` runs misread as "MLX is already
63+ installed", silently skipping the build and bombing out in
64+ ` elixir_make ` with `make: ** * No rule to make target
65+ '.../mlx.metallib'`. The compile-time check now requires both
66+ ` lib/libmlx.a ` and ` lib/mlx.metallib ` to be present before
67+ trusting the dir.
68+ - Concurrent invocations of ` build-mlx.sh ` against the same install
69+ prefix are now serialised via a ` mkdir ` -based lock with
70+ stale-PID reclaim. ElixirLS uses its own build path
71+ (` .elixir_ls/build/... ` ) so an LSP-driven ` mix compile ` and a CLI
72+ ` mix compile.emily_mlx --force ` lock on * different*
73+ ` Mix.Project.with_build_lock ` keys and freely raced into the same
74+ MLX cache dir, clobbering each other's ` ${PREFIX}.build/ `
75+ mid-build and surfacing as `clang ... Rename failed: ... No such
76+ file or directory` during Metal-shader compilation.
77+ - CMake's FetchContent sub-build of metal_cpp / json / fmt during
78+ configure runs with ` CMAKE_BUILD_PARALLEL_LEVEL=1 ` , dodging a
79+ race in its download → extract → rename → stamp-touch pipeline
80+ that surfaced as ` getcwd: cannot access parent directories `
81+ followed by ` cd: <dir>/_deps: No such file or directory ` . The
82+ main MLX build still runs at full NCPU jobs.
83+ - The MLX scratch build dir (` ${PREFIX}.build ` ) is preserved on
84+ configure failure so ` CMakeError.log ` survives for diagnostics.
85+
86+ ### Removed
87+
88+ - ` config/local.exs ` override (obsoleted by the env-var plumbing).
89+ - ` .github/workflows/release-mlx.yml ` (MLX build is folded into the
90+ NIF workflow).
91+ - ` scripts/build-mlx-prebuilt.sh ` (superseded by in-tree
92+ ` scripts/build-mlx.sh ` ).
93+ - ` scripts/smoke-test-package.sh ` and the tagged ` smoke-test ` job in
94+ ` ci.yml ` (simulated a source-compile consumer, no longer
95+ applicable).
96+
97+ See ` MAINTAINING.md ` for the updated release flow.
98+
1099## 0.2.2 - 2026-04-23
11100
12101### Fixed
0 commit comments