diff --git a/misc/ollama/Makefile b/misc/ollama/Makefile index b6af2c9d50ed..2c6d9d0c6a26 100644 --- a/misc/ollama/Makefile +++ b/misc/ollama/Makefile @@ -1,172 +1,172 @@ PORTNAME= ollama DISTVERSIONPREFIX= v -DISTVERSION= 0.20.2 +DISTVERSION= 0.20.4 CATEGORIES= misc # machine-learning MAINTAINER= yuri@FreeBSD.org COMMENT= Run Llama 2, Mistral, and other large language models WWW= https://ollama.com \ https://github.com/ollama/ollama LICENSE= MIT LICENSE_FILE= ${WRKSRC}/LICENSE BROKEN_i386= fails to compile: x/mlxrunner/mlx/memory.go:40:11: 1 << (4 * 10) (untyped int constant 1099511627776) overflows int 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 \ patchelf:sysutils/patchelf USES= cmake:indirect go:1.24+,modules localbase pkgconfig USE_RC_SUBR= ollama GO_MODULE= github.com/yurivict/${PORTNAME} # fork with FreeBSD patches GO_TARGET= . GO_ENV+= CGO_CXXFLAGS="${CXXFLAGS}" MLX_CORE_VERSION= 0.31.1 MLX_C_VERSION= 0.6.0 JSON_VERSION= 3.11.3 PLIST_FILES= bin/${PORTNAME} \ bin/ollama-limit-gpu-layers XARCH!= uname -p OPTIONS_GROUP= BACKENDS OPTIONS_GROUP_BACKENDS= 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 \ lib/ollama/libggml-base.so.0 .if ${XARCH} == "amd64" || ${XARCH} == "i386" CPU_PLIST_FILES+= lib/ollama/libggml-cpu-alderlake.so \ lib/ollama/libggml-cpu-haswell.so \ lib/ollama/libggml-cpu-icelake.so \ lib/ollama/libggml-cpu-sandybridge.so \ lib/ollama/libggml-cpu-skylakex.so \ lib/ollama/libggml-cpu-sse42.so \ lib/ollama/libggml-cpu-x64.so .endif VULKAN_DESC= Build Vulkan GPU backend shared library VULKAN_BUILD_DEPENDS= glslc:graphics/shaderc \ ${LOCALBASE}/include/vulkan/vulkan.h:graphics/vulkan-headers VULKAN_LIB_DEPENDS= libvulkan.so:graphics/vulkan-loader VULKAN_PLIST_FILES= lib/ollama/vulkan/libggml-vulkan.so MLX_DESC= Build MLX backend for image generation (CPU) 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 _CMAKE_FLAGS= -DCMAKE_BUILD_TYPE=Release -DGGML_BACKEND_DL=ON -DGGML_BACKEND_DIR=${PREFIX}/lib/ollama .include .if ${PORT_OPTIONS:MMLX} GO_BUILDFLAGS+= -tags mlx DISTFILES+= v${MLX_CORE_VERSION}.tar.gz:mlxsrc \ v${MLX_C_VERSION}.tar.gz:mlxcsrc \ json.tar.xz:jsonsrc MASTER_SITES+= https://github.com/ml-explore/mlx/archive/refs/tags/:mlxsrc \ https://github.com/ml-explore/mlx-c/archive/refs/tags/:mlxcsrc \ https://github.com/nlohmann/json/releases/download/v${JSON_VERSION}/:jsonsrc .endif CONFLICTS_BUILD= ggml post-patch: # change import path to the fork @cd ${WRKSRC} && \ (${GREP} -rl ollama/ollama | ${XARGS} ${REINPLACE_CMD} -i '' -e 's|ollama/ollama|yurivict/ollama|g') # update version in go.mod and version.go @${REINPLACE_CMD} -e 's|var Version string = "0.0.0"|var Version string = "${PORTVERSION}"|g' \ ${WRKSRC}/go.mod ${WRKSRC}/version/version.go pre-build-CPU-on: @${MKDIR} ${WRKSRC}/build && \ cd ${WRKSRC}/build && \ ${CMAKE_BIN} ${_CMAKE_FLAGS} .. && \ ${MAKE_CMD} ggml-base && \ ${MAKE_CMD} ggml-cpu pre-build-VULKAN-on: .if !${PORT_OPTIONS:MCPU} && !${PORT_OPTIONS:MMLX} @${MKDIR} ${WRKSRC}/build && \ cd ${WRKSRC}/build && \ ${CMAKE_BIN} ${_CMAKE_FLAGS} .. .endif @cd ${WRKSRC}/build && \ ${MAKE_CMD} ggml-vulkan post-patch-MLX-on: # 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 /{print "#include ";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 && \ cd ${WRKSRC}/build && \ OLLAMA_MLX_SOURCE=${WRKDIR}/mlx-${MLX_CORE_VERSION} \ OLLAMA_MLX_C_SOURCE=${WRKDIR}/mlx-c-${MLX_C_VERSION} \ ${CMAKE_BIN} ${_CMAKE_FLAGS} \ -DMLX_ENGINE:BOOL=ON \ -DFETCHCONTENT_FULLY_DISCONNECTED:BOOL=ON \ -DFETCHCONTENT_SOURCE_DIR_JSON:PATH=${WRKDIR}/json \ -DUSE_SYSTEM_FMT:BOOL=ON \ -DMLX_BUILD_TESTS:BOOL=OFF \ -DMLX_BUILD_EXAMPLES:BOOL=OFF \ .. @cd ${WRKSRC}/build && \ ${MAKE_CMD} mlx mlxc post-install: # pending https://github.com/ollama/ollama/issues/6407 ${INSTALL_SCRIPT} ${FILESDIR}/ollama-limit-gpu-layers ${STAGEDIR}${PREFIX}/bin post-install-CPU-on: @${MKDIR} ${STAGEDIR}${PREFIX}/lib/ollama ${INSTALL_LIB} ${WRKSRC}/build/lib/ollama/libggml-base.so \ ${STAGEDIR}${PREFIX}/lib/ollama/ # Create the SONAME symlink so that libggml-vulkan.so and libggml-cpu-*.so # can resolve their NEEDED libggml-base.so.0 dependency via dlopen ${LN} -sf libggml-base.so ${STAGEDIR}${PREFIX}/lib/ollama/libggml-base.so.0 @for f in ${WRKSRC}/build/lib/ollama/libggml-cpu*.so; do \ ${INSTALL_LIB} $$f ${STAGEDIR}${PREFIX}/lib/ollama/; \ done post-install-VULKAN-on: @${MKDIR} ${STAGEDIR}${PREFIX}/lib/ollama/vulkan ${INSTALL_LIB} ${WRKSRC}/build/lib/ollama/libggml-vulkan.so \ ${STAGEDIR}${PREFIX}/lib/ollama/vulkan/ post-install-MLX-on: @${MKDIR} ${STAGEDIR}${PREFIX}/lib/ollama ${INSTALL_LIB} ${WRKSRC}/build/lib/ollama/libmlx.so \ ${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} && \ ${SETENVI} ${WRK_ENV} ${MAKE_ENV} ${GO_ENV} ${GO_CMD} test ./... .include diff --git a/misc/ollama/distinfo b/misc/ollama/distinfo index 35c9483925ba..b9706b3a09e0 100644 --- a/misc/ollama/distinfo +++ b/misc/ollama/distinfo @@ -1,11 +1,11 @@ -TIMESTAMP = 1775410961 -SHA256 (go/misc_ollama/ollama-v0.20.2/v0.31.1.tar.gz) = 37e2a585a2bb28bcd3432af1c45d5c1ba8d560704ae285c3f9fd22a041e37004 -SIZE (go/misc_ollama/ollama-v0.20.2/v0.31.1.tar.gz) = 4163405 -SHA256 (go/misc_ollama/ollama-v0.20.2/v0.6.0.tar.gz) = 6ec2eab86ed3ce661c0d9b834027870651546138b7b4470fa8ef5533498c79aa -SIZE (go/misc_ollama/ollama-v0.20.2/v0.6.0.tar.gz) = 170186 -SHA256 (go/misc_ollama/ollama-v0.20.2/json.tar.xz) = d6c65aca6b1ed68e7a182f4757257b107ae403032760ed6ef121c9d55e81757d -SIZE (go/misc_ollama/ollama-v0.20.2/json.tar.xz) = 110988 -SHA256 (go/misc_ollama/ollama-v0.20.2/v0.20.2.mod) = e660ffa37ad33611a4c1248967204e578f07ada9941e63ffe6a6fe3e95ac5039 -SIZE (go/misc_ollama/ollama-v0.20.2/v0.20.2.mod) = 4757 -SHA256 (go/misc_ollama/ollama-v0.20.2/v0.20.2.zip) = 6841003d5466a7ba7d6da6b8e8af89d020f380bb37b25b85316b23e729287533 -SIZE (go/misc_ollama/ollama-v0.20.2/v0.20.2.zip) = 26648607 +TIMESTAMP = 1775698154 +SHA256 (go/misc_ollama/ollama-v0.20.4/v0.31.1.tar.gz) = 37e2a585a2bb28bcd3432af1c45d5c1ba8d560704ae285c3f9fd22a041e37004 +SIZE (go/misc_ollama/ollama-v0.20.4/v0.31.1.tar.gz) = 4163405 +SHA256 (go/misc_ollama/ollama-v0.20.4/v0.6.0.tar.gz) = 6ec2eab86ed3ce661c0d9b834027870651546138b7b4470fa8ef5533498c79aa +SIZE (go/misc_ollama/ollama-v0.20.4/v0.6.0.tar.gz) = 170186 +SHA256 (go/misc_ollama/ollama-v0.20.4/json.tar.xz) = d6c65aca6b1ed68e7a182f4757257b107ae403032760ed6ef121c9d55e81757d +SIZE (go/misc_ollama/ollama-v0.20.4/json.tar.xz) = 110988 +SHA256 (go/misc_ollama/ollama-v0.20.4/v0.20.4.mod) = e660ffa37ad33611a4c1248967204e578f07ada9941e63ffe6a6fe3e95ac5039 +SIZE (go/misc_ollama/ollama-v0.20.4/v0.20.4.mod) = 4757 +SHA256 (go/misc_ollama/ollama-v0.20.4/v0.20.4.zip) = 8fb0cd28b99e0386676d81019ebc31aa4d84cdb189af7d306652a1e5d5e3fa05 +SIZE (go/misc_ollama/ollama-v0.20.4/v0.20.4.zip) = 26673929 diff --git a/misc/ollama/files/patch-CMakeLists.txt b/misc/ollama/files/patch-CMakeLists.txt index 977273f77085..359b7f60b1f7 100644 --- a/misc/ollama/files/patch-CMakeLists.txt +++ b/misc/ollama/files/patch-CMakeLists.txt @@ -1,13 +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) +--- CMakeLists.txt.orig 1979-11-30 08:00:00 UTC ++++ CMakeLists.txt +@@ -52,6 +52,10 @@ if(APPLE) set(CMAKE_BUILD_RPATH "@loader_path") set(CMAKE_INSTALL_RPATH "@loader_path") -+ set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) + 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) ++ set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) endif() + set(OLLAMA_BUILD_DIR ${CMAKE_BINARY_DIR}/lib/ollama) diff --git a/misc/ollama/files/patch-x_imagegen_mlx_CMakeLists.txt b/misc/ollama/files/patch-x_imagegen_mlx_CMakeLists.txt index 2ebbf324d1a1..f61429b0adfb 100644 --- a/misc/ollama/files/patch-x_imagegen_mlx_CMakeLists.txt +++ b/misc/ollama/files/patch-x_imagegen_mlx_CMakeLists.txt @@ -1,31 +1,40 @@ ---- x/imagegen/mlx/CMakeLists.txt.orig 2026-03-27 00:01:53 UTC +--- x/imagegen/mlx/CMakeLists.txt.orig 2026-04-09 01:41:08 UTC +++ x/imagegen/mlx/CMakeLists.txt -@@ -98,28 +98,6 @@ file(COPY ${_mlx_c_hdrs} DESTINATION "${CMAKE_SOURCE_D +@@ -98,37 +98,6 @@ file(COPY ${_mlx_c_hdrs} DESTINATION "${CMAKE_SOURCE_D file(GLOB _mlx_c_hdrs "${mlx-c_SOURCE_DIR}/mlx/c/*.h") file(COPY ${_mlx_c_hdrs} DESTINATION "${CMAKE_SOURCE_DIR}/x/mlxrunner/mlx/include/mlx/c/") -# Regenerate Go/C shim wrappers from the (possibly updated) headers. --find_program(GO_EXECUTABLE go REQUIRED) --message(STATUS "Regenerating MLX Go wrappers") +-# Skip during cross-compilation — the generated files are arch-independent. +-if(CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR OR NOT APPLE) +- find_program(GO_EXECUTABLE go REQUIRED) +- message(STATUS "Regenerating MLX Go wrappers") - --# Go's cgo splits CC on whitespace, so a CC like "C:/Program Files/…/cl.exe" --# (set by cmake on Windows) breaks with "C:/Program" not found. Clear CC --# when it contains spaces so cgo falls back to its default (gcc). --if(WIN32 AND "$ENV{CC}" MATCHES " ") +- # CGo's probe compilation is sensitive to CGO_CFLAGS/CGO_CXXFLAGS and CC. +- # Clear them so go generate uses default compiler settings: +- # - On Windows, CC may contain spaces (e.g., "C:/Program Files/.../cl.exe") +- # which breaks CGo's CC parsing. +- # - On macOS, CGO_CFLAGS with -mmacosx-version-min breaks header search +- # when cmake also sets CMAKE_OSX_DEPLOYMENT_TARGET. - set(_SAVE_CC "$ENV{CC}") +- set(_SAVE_CGO_CFLAGS "$ENV{CGO_CFLAGS}") +- set(_SAVE_CGO_CXXFLAGS "$ENV{CGO_CXXFLAGS}") - set(ENV{CC} "") --endif() +- set(ENV{CGO_CFLAGS} "") +- set(ENV{CGO_CXXFLAGS} "") - --execute_process( -- COMMAND ${GO_EXECUTABLE} generate ./x/... -- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} -- COMMAND_ERROR_IS_FATAL ANY --) +- execute_process( +- COMMAND ${GO_EXECUTABLE} generate ./x/... +- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} +- COMMAND_ERROR_IS_FATAL ANY +- ) - --if(DEFINED _SAVE_CC) - set(ENV{CC} "${_SAVE_CC}") +- set(ENV{CGO_CFLAGS} "${_SAVE_CGO_CFLAGS}") +- set(ENV{CGO_CXXFLAGS} "${_SAVE_CGO_CXXFLAGS}") +-else() +- message(STATUS "Skipping MLX Go wrapper generation (cross-compiling)") -endif() -- + # For local dev builds, override MLX_VERSION with git describe output if(TARGET mlx_version AND DEFINED FETCHCONTENT_SOURCE_DIR_MLX) - execute_process( diff --git a/misc/ollama/files/patch-x_imagegen_mlx_mlx.go b/misc/ollama/files/patch-x_imagegen_mlx_mlx.go index a77de5f2beed..cee6e3f8ef1d 100644 --- a/misc/ollama/files/patch-x_imagegen_mlx_mlx.go +++ b/misc/ollama/files/patch-x_imagegen_mlx_mlx.go @@ -1,66 +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 @@ +--- x/imagegen/mlx/mlx.go.orig 1979-11-30 08:00:00 UTC ++++ x/imagegen/mlx/mlx.go +@@ -4,6 +4,7 @@ package mlx #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 @@ +@@ -23,6 +24,10 @@ static inline mlx_stream default_stream() { 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 @@ +@@ -1512,14 +1517,21 @@ func LoadSafetensorsNative(path string) (*SafetensorsF 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 @@ +@@ -1755,12 +1767,17 @@ func findMLXLibrary() string { 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_imagegen_models_zimage_vae.go b/misc/ollama/files/patch-x_imagegen_models_zimage_vae.go index 0c9e990b52ba..1cd9e0eaa6b8 100644 --- a/misc/ollama/files/patch-x_imagegen_models_zimage_vae.go +++ b/misc/ollama/files/patch-x_imagegen_models_zimage_vae.go @@ -1,35 +1,35 @@ ---- x/imagegen/models/zimage/vae.go.orig 1979-11-30 00:00:00.000000000 -0800 +--- x/imagegen/models/zimage/vae.go.orig 1979-11-30 08:00:00 UTC +++ x/imagegen/models/zimage/vae.go -@@ -332,6 +332,16 @@ +@@ -332,6 +332,16 @@ func (rb *ResnetBlock2D) Forward(x *mlx.Array) *mlx.Ar // Forward applies the ResNet block with staged evaluation func (rb *ResnetBlock2D) Forward(x *mlx.Array) *mlx.Array { + // Keep x alive across intermediate Eval calls (cleanup() would free it otherwise). + // The residual connection at the end needs the original x. + wasKept := x.Kept() + mlx.Keep(x) + defer func() { + if !wasKept { + x.Free() + } + }() + var h *mlx.Array // Stage 1: norm1 -@@ -461,6 +471,15 @@ +@@ -461,6 +471,15 @@ func (ab *VAEAttentionBlock) Forward(x *mlx.Array) *ml // Input and output are in NHWC format [B, H, W, C] func (ab *VAEAttentionBlock) Forward(x *mlx.Array) *mlx.Array { residual := x + // Keep residual alive across intermediate Eval calls. + // The residual addition at stage 3 needs the original input. + wasKept := residual.Kept() + mlx.Keep(residual) + defer func() { + if !wasKept { + residual.Free() + } + }() shape := x.Shape() B := shape[0] H := shape[1] diff --git a/misc/ollama/files/patch-x_imagegen_server.go b/misc/ollama/files/patch-x_imagegen_server.go index a49851568dec..f22dcbbc665a 100644 --- a/misc/ollama/files/patch-x_imagegen_server.go +++ b/misc/ollama/files/patch-x_imagegen_server.go @@ -1,26 +1,26 @@ -- same issue as first chunk: https://github.com/ollama/ollama/issues/15107 ---- x/imagegen/server.go.orig +--- x/imagegen/server.go.orig 1979-11-30 08:00:00 UTC +++ x/imagegen/server.go -@@ -55,7 +55,9 @@ +@@ -55,7 +55,9 @@ func NewServer(modelName string) (*Server, error) { return &Server{ modelName: modelName, done: make(chan error, 1), - client: &http.Client{Timeout: 10 * time.Minute}, + // No client-level timeout: image generation on CPU can take many minutes. + // Cancellation is handled via request context. + client: &http.Client{}, }, nil } -@@ -116,8 +118,8 @@ +@@ -116,8 +118,8 @@ func (s *Server) Load(ctx context.Context, _ ml.System cmd := exec.Command(exe, "runner", "--imagegen-engine", "--model", s.modelName, "--port", strconv.Itoa(port)) cmd.Env = os.Environ() - // On Linux, set LD_LIBRARY_PATH to include MLX library directories - if runtime.GOOS == "linux" { + // On Linux and FreeBSD, set LD_LIBRARY_PATH to include MLX library directories + if runtime.GOOS == "linux" || runtime.GOOS == "freebsd" { // Build library paths: start with LibOllamaPath, then add any mlx_* subdirectories libraryPaths := []string{ml.LibOllamaPath} if mlxDirs, err := filepath.Glob(filepath.Join(ml.LibOllamaPath, "mlx_*")); err == nil { diff --git a/misc/ollama/files/patch-x_mlxrunner_mlx_dynamic.go b/misc/ollama/files/patch-x_mlxrunner_mlx_dynamic.go index 1d7586234740..76e6d0bec723 100644 --- a/misc/ollama/files/patch-x_mlxrunner_mlx_dynamic.go +++ b/misc/ollama/files/patch-x_mlxrunner_mlx_dynamic.go @@ -1,32 +1,29 @@ ---- 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 @@ +--- x/mlxrunner/mlx/dynamic.go.orig 2026-04-09 01:42:19 UTC ++++ x/mlxrunner/mlx/dynamic.go +@@ -83,7 +83,7 @@ func libOllamaRoots() []string { + case "darwin": + roots = append(roots, filepath.Join(exeDir, "lib", "ollama")) + roots = append(roots, exeDir) // app bundle: Contents/Resources/ +- case "linux": ++ case "linux", "freebsd": + roots = append(roots, filepath.Join(exeDir, "..", "lib", "ollama")) + case "windows": + roots = append(roots, filepath.Join(exeDir, "lib", "ollama")) +@@ -143,7 +143,7 @@ func prependLibraryPath(dir string) { switch runtime.GOOS { - case "windows": - libraryName = "mlxc.dll" + case "darwin": + envVar = "DYLD_LIBRARY_PATH" - case "linux": + case "linux", "freebsd": - libraryName = "libmlxc.so" - } - -@@ -93,7 +93,7 @@ + envVar = "LD_LIBRARY_PATH" + default: + return +@@ -157,7 +157,7 @@ func init() { 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 { diff --git a/misc/ollama/pkg-message b/misc/ollama/pkg-message index 0ad67fb6566c..f5cd56fa789b 100644 --- a/misc/ollama/pkg-message +++ b/misc/ollama/pkg-message @@ -1,57 +1,57 @@ [ { type: install message: <