Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Mar 2026 08:27:09 +0000
From:      Yuri Victorovich <yuri@FreeBSD.org>
To:        ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org
Subject:   git: 52a32dce00e4 - main - misc/ollama: fix MLX option (image generation)
Message-ID:  <69c63f5d.1ec5f.29f49c32@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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 {


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69c63f5d.1ec5f.29f49c32>