git: 52a32dce00e4 - main - misc/ollama: fix MLX option (image generation)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 27 Mar 2026 08:27:09 UTC
The branch main has been updated by yuri:
URL: https://cgit.FreeBSD.org/ports/commit/?id=52a32dce00e4001d2afe543ce8635e963e7e488a
commit 52a32dce00e4001d2afe543ce8635e963e7e488a
Author: Yuri Victorovich <yuri@FreeBSD.org>
AuthorDate: 2026-03-27 02:39:36 +0000
Commit: Yuri Victorovich <yuri@FreeBSD.org>
CommitDate: 2026-03-27 08:27:07 +0000
misc/ollama: fix MLX option (image generation)
---
misc/ollama/Makefile | 28 ++++++---
misc/ollama/distinfo | 8 +--
misc/ollama/files/freebsd_memory.h | 19 +++++++
misc/ollama/files/patch-CMakeLists.txt | 13 +++++
misc/ollama/files/patch-x_imagegen_mlx_mlx.go | 66 ++++++++++++++++++++++
misc/ollama/files/patch-x_mlxrunner_mlx_dynamic.go | 32 +++++++++++
6 files changed, 154 insertions(+), 12 deletions(-)
diff --git a/misc/ollama/Makefile b/misc/ollama/Makefile
index c8778fe3d2da..f10ae5724905 100644
--- a/misc/ollama/Makefile
+++ b/misc/ollama/Makefile
@@ -1,6 +1,7 @@
PORTNAME= ollama
DISTVERSIONPREFIX= v
DISTVERSION= 0.18.3
+PORTREVISION= 1
CATEGORIES= misc # machine-learning
MAINTAINER= yuri@FreeBSD.org
@@ -16,7 +17,8 @@ BROKEN_i386= fails to compile: x/mlxrunner/mlx/memory.go:40:11: 1 << (4 * 10) (u
BUILD_DEPENDS= bash:shells/bash \
${LOCALBASE}/include/miniaudio/miniaudio.h:audio/miniaudio \
${LOCALBASE}/include/nlohmann/json_fwd.hpp:devel/nlohmann-json \
- ${LOCALBASE}/include/stb/stb_image.h:devel/stb
+ ${LOCALBASE}/include/stb/stb_image.h:devel/stb \
+ patchelf:sysutils/patchelf
USES= cmake:indirect go:1.24+,modules localbase pkgconfig
@@ -24,8 +26,8 @@ GO_MODULE= github.com/yurivict/${PORTNAME} # fork with FreeBSD patches
GO_TARGET= .
GO_ENV+= CGO_CXXFLAGS="${CXXFLAGS}"
-MLX_CORE_VERSION= 0.30.6
-MLX_C_VERSION= 0.5.0
+MLX_CORE_VERSION= 0.31.1
+MLX_C_VERSION= 0.6.0
JSON_VERSION= 3.11.3
PLIST_FILES= bin/${PORTNAME} \
@@ -33,7 +35,7 @@ PLIST_FILES= bin/${PORTNAME} \
OPTIONS_GROUP= BACKENDS
OPTIONS_GROUP_BACKENDS= CPU VULKAN MLX
-OPTIONS_DEFAULT= CPU VULKAN #MLX
+OPTIONS_DEFAULT= CPU VULKAN MLX
CPU_DESC= Build CPU backend shared libraries for various SIMD instruction sets
CPU_PLIST_FILES= lib/ollama/libggml-base.so \
@@ -56,8 +58,6 @@ MLX_BUILD_DEPENDS= ${LOCALBASE}/lib/cmake/fmt/fmt-config.cmake:devel/libfmt
MLX_LIB_DEPENDS= libopenblas.so:math/openblas
MLX_PLIST_FILES= lib/ollama/libmlx.so \
lib/ollama/libmlxc.so
-MLX_BROKEN= build fails in 1.18.3
-
_CMAKE_FLAGS= -DCMAKE_BUILD_TYPE=Release -DGGML_BACKEND_DL=ON -DGGML_BACKEND_DIR=${PREFIX}/lib/ollama
.include <bsd.port.options.mk>
@@ -97,12 +97,22 @@ pre-build-VULKAN-on:
${MAKE_CMD} ggml-vulkan
post-patch-MLX-on:
- # FreeBSD compatibility fix: add missing netinet/in.h include
- @${AWK} '/^#include <fcntl.h>/{print;print "#include <netinet/in.h>";next}1' \
+ # FreeBSD compatibility fix: netinet/in.h (defines IPPROTO_TCP) is not
+ # pulled in transitively by netinet/tcp.h on FreeBSD as it is on Linux.
+ @${AWK} '/^#include <netinet\/tcp.h>/{print "#include <netinet/in.h>";print;next}1' \
${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/distributed/ring/ring.cpp > \
${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/distributed/ring/ring.cpp.new && \
${MV} ${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/distributed/ring/ring.cpp.new \
${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/distributed/ring/ring.cpp
+ # FreeBSD memory size fix: add hw.physmem sysctl query so MLX sets its
+ # memory_limit from actual RAM instead of using the 8 GB hardcoded fallback.
+ ${INSTALL_DATA} ${FILESDIR}/freebsd_memory.h \
+ ${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/backend/no_gpu/freebsd_memory.h
+ @${AWK} '/^#elif defined\(__linux__\)/{print "#elif defined(__FreeBSD__)";print "#include \"mlx/backend/no_gpu/freebsd_memory.h\"";print;next}1' \
+ ${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/backend/no_gpu/allocator.cpp > \
+ ${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/backend/no_gpu/allocator.cpp.new && \
+ ${MV} ${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/backend/no_gpu/allocator.cpp.new \
+ ${WRKDIR}/mlx-${MLX_CORE_VERSION}/mlx/backend/no_gpu/allocator.cpp
pre-build-MLX-on:
@${MKDIR} ${WRKSRC}/build && \
@@ -142,6 +152,8 @@ post-install-MLX-on:
${STAGEDIR}${PREFIX}/lib/ollama/
${INSTALL_LIB} ${WRKSRC}/build/lib/ollama/libmlxc.so \
${STAGEDIR}${PREFIX}/lib/ollama/
+ patchelf --set-rpath '$$ORIGIN' ${STAGEDIR}${PREFIX}/lib/ollama/libmlx.so
+ patchelf --set-rpath '$$ORIGIN' ${STAGEDIR}${PREFIX}/lib/ollama/libmlxc.so
do-test:
@cd ${WRKSRC} && \
diff --git a/misc/ollama/distinfo b/misc/ollama/distinfo
index 089f57d96267..a1fd40ae1b52 100644
--- a/misc/ollama/distinfo
+++ b/misc/ollama/distinfo
@@ -1,8 +1,8 @@
TIMESTAMP = 1774561377
-SHA256 (go/misc_ollama/ollama-v0.18.3/v0.30.6.tar.gz) = 04d8e3c5d3c3ae748145ffe51d3ad8b72493e1e8597fc0f9dc631ed620b12618
-SIZE (go/misc_ollama/ollama-v0.18.3/v0.30.6.tar.gz) = 4138686
-SHA256 (go/misc_ollama/ollama-v0.18.3/v0.5.0.tar.gz) = dcfc404d7004e6da70170c669dbc920913cb25a59c9f7dac781caf92e524cc86
-SIZE (go/misc_ollama/ollama-v0.18.3/v0.5.0.tar.gz) = 169957
+SHA256 (go/misc_ollama/ollama-v0.18.3/v0.31.1.tar.gz) = 37e2a585a2bb28bcd3432af1c45d5c1ba8d560704ae285c3f9fd22a041e37004
+SIZE (go/misc_ollama/ollama-v0.18.3/v0.31.1.tar.gz) = 4163405
+SHA256 (go/misc_ollama/ollama-v0.18.3/v0.6.0.tar.gz) = 6ec2eab86ed3ce661c0d9b834027870651546138b7b4470fa8ef5533498c79aa
+SIZE (go/misc_ollama/ollama-v0.18.3/v0.6.0.tar.gz) = 170186
SHA256 (go/misc_ollama/ollama-v0.18.3/json.tar.xz) = d6c65aca6b1ed68e7a182f4757257b107ae403032760ed6ef121c9d55e81757d
SIZE (go/misc_ollama/ollama-v0.18.3/json.tar.xz) = 110988
SHA256 (go/misc_ollama/ollama-v0.18.3/v0.18.3.mod) = e660ffa37ad33611a4c1248967204e578f07ada9941e63ffe6a6fe3e95ac5039
diff --git a/misc/ollama/files/freebsd_memory.h b/misc/ollama/files/freebsd_memory.h
new file mode 100644
index 000000000000..03577ceba114
--- /dev/null
+++ b/misc/ollama/files/freebsd_memory.h
@@ -0,0 +1,19 @@
+// Copyright © 2025 Apple Inc.
+
+#pragma once
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+namespace {
+
+size_t get_memory_size() {
+ size_t physmem = 0;
+ size_t len = sizeof(physmem);
+ if (sysctlbyname("hw.physmem", &physmem, &len, NULL, 0) != 0) {
+ return 0;
+ }
+ return physmem;
+}
+
+} // namespace
diff --git a/misc/ollama/files/patch-CMakeLists.txt b/misc/ollama/files/patch-CMakeLists.txt
new file mode 100644
index 000000000000..977273f77085
--- /dev/null
+++ b/misc/ollama/files/patch-CMakeLists.txt
@@ -0,0 +1,13 @@
+--- CMakeLists.txt.orig 2026-03-26 23:34:20.357190000 -0700
++++ CMakeLists.txt 2026-03-26 23:34:25.336566000 -0700
+@@ -51,6 +51,10 @@
+ if(APPLE)
+ set(CMAKE_BUILD_RPATH "@loader_path")
+ set(CMAKE_INSTALL_RPATH "@loader_path")
++ set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
++elseif(UNIX)
++ set(CMAKE_BUILD_RPATH "$ORIGIN")
++ set(CMAKE_INSTALL_RPATH "$ORIGIN")
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
+ endif()
+
diff --git a/misc/ollama/files/patch-x_imagegen_mlx_mlx.go b/misc/ollama/files/patch-x_imagegen_mlx_mlx.go
new file mode 100644
index 000000000000..a77de5f2beed
--- /dev/null
+++ b/misc/ollama/files/patch-x_imagegen_mlx_mlx.go
@@ -0,0 +1,66 @@
+--- x/imagegen/mlx/mlx.go.orig 1979-11-30 00:00:00.000000000 -0800
++++ x/imagegen/mlx/mlx.go 2026-03-27 00:29:56.018820000 -0700
+@@ -4,6 +4,7 @@
+ #cgo CFLAGS: -O3 -I${SRCDIR}/../../mlxrunner/mlx/include -I${SRCDIR}
+ #cgo darwin LDFLAGS: -lc++ -framework Metal -framework Foundation -framework Accelerate
+ #cgo linux LDFLAGS: -lstdc++ -ldl
++#cgo freebsd LDFLAGS: -lc++ -ldl
+ #cgo windows LDFLAGS: -lstdc++
+
+ // Use generated wrappers instead of direct MLX headers
+@@ -23,6 +24,10 @@
+ static inline mlx_stream default_stream() {
+ if (_default_stream.ctx == NULL) {
+ _default_stream = mlx_default_gpu_stream_new();
++ // On CPU-only systems (no Metal, no CUDA), fall back to the CPU stream.
++ if (_default_stream.ctx == NULL) {
++ _default_stream = mlx_default_cpu_stream_new();
++ }
+ }
+ return _default_stream;
+ }
+@@ -1512,14 +1517,21 @@
+ defer C.free(unsafe.Pointer(cPath))
+
+ stream := C.default_stream()
+- if runtime.GOOS == "darwin" {
++ if runtime.GOOS == "darwin" || runtime.GOOS == "freebsd" {
+ stream = C.cpu_stream()
+ }
+
+ var arrays C.mlx_map_string_to_array
+ var metadata C.mlx_map_string_to_string
+- if C.mlx_load_safetensors(&arrays, &metadata, cPath, stream) != 0 {
+- return nil, fmt.Errorf("failed to load safetensors: %s", path)
++ C.mlx_set_safe_init_mode()
++ rc := C.mlx_load_safetensors(&arrays, &metadata, cPath, stream)
++ C.mlx_set_default_error_mode()
++ if rc != 0 {
++ errMsg := ""
++ if C.mlx_had_init_error() != 0 {
++ errMsg = ": " + C.GoString(C.mlx_get_init_error())
++ }
++ return nil, fmt.Errorf("failed to load safetensors: %s%s", path, errMsg)
+ }
+ return &SafetensorsFile{arrays: arrays, metadata: metadata}, nil
+ }
+@@ -1755,12 +1767,17 @@
+ return candidate
+ }
+
+- // Check exe_dir/lib/ollama/mlx* subdirectories
+- // and exe_dir/../lib/ollama/mlx* (standard bin/lib sibling layout)
++ // Check exe_dir/lib/ollama and exe_dir/../lib/ollama directly,
++ // and their mlx* subdirectories (standard bin/lib sibling layout)
+ for _, libOllamaDir := range []string{
+ filepath.Join(exeDir, "lib", "ollama"),
+ filepath.Join(exeDir, "..", "lib", "ollama"),
+ } {
++ // Check the directory itself first (FreeBSD/Linux installed layout)
++ candidate = filepath.Join(libOllamaDir, libName)
++ if _, err := os.Stat(candidate); err == nil {
++ return candidate
++ }
+ if mlxDirs, err := filepath.Glob(filepath.Join(libOllamaDir, "mlx*")); err == nil {
+ for _, mlxDir := range mlxDirs {
+ candidate = filepath.Join(mlxDir, libName)
diff --git a/misc/ollama/files/patch-x_mlxrunner_mlx_dynamic.go b/misc/ollama/files/patch-x_mlxrunner_mlx_dynamic.go
new file mode 100644
index 000000000000..1d7586234740
--- /dev/null
+++ b/misc/ollama/files/patch-x_mlxrunner_mlx_dynamic.go
@@ -0,0 +1,32 @@
+--- x/mlxrunner/mlx/dynamic.go.orig 2026-03-26 19:59:35.600583000 -0700
++++ x/mlxrunner/mlx/dynamic.go 2026-03-26 20:00:54.082312000 -0700
+@@ -72,7 +72,7 @@
+ switch runtime.GOOS {
+ case "windows":
+ libraryName = "mlxc.dll"
+- case "linux":
++ case "linux", "freebsd":
+ libraryName = "libmlxc.so"
+ }
+
+@@ -93,7 +93,7 @@
+
+ func init() {
+ switch runtime.GOOS {
+- case "darwin", "linux", "windows":
++ case "darwin", "linux", "freebsd", "windows":
+
+ default:
+ return
+@@ -126,7 +126,10 @@
+ if eval, err := filepath.EvalSymlinks(exe); err == nil {
+ exe = eval
+ }
+- searchDirs = append(searchDirs, filepath.Dir(exe))
++ exeDir := filepath.Dir(exe)
++ searchDirs = append(searchDirs, exeDir)
++ // On Linux/FreeBSD the installed layout is bin/ollama + lib/ollama/libmlxc.so
++ searchDirs = append(searchDirs, filepath.Join(exeDir, "..", "lib", "ollama"))
+ }
+
+ if cwd, err := os.Getwd(); err == nil {