|
@@ -41,36 +41,48 @@ func sink(level C.int, text *C.char, _ unsafe.Pointer) {
|
|
|
}
|
|
|
|
|
|
var OnceLoad = sync.OnceFunc(func() {
|
|
|
- var lib struct{ name, defaultValue string }
|
|
|
+ exe, err := os.Executable()
|
|
|
+ if err != nil {
|
|
|
+ slog.Warn("failed to get executable path", "error", err)
|
|
|
+ exe = "."
|
|
|
+ }
|
|
|
+
|
|
|
+ // PATH, LD_LIBRARY_PATH, and DYLD_LIBRARY_PATH are often
|
|
|
+ // set by the parent process, however, use a default value
|
|
|
+ // if the environment variable is not set.
|
|
|
+ var name, value string
|
|
|
switch runtime.GOOS {
|
|
|
- case "darwin", "linux":
|
|
|
- lib.name = "LD_LIBRARY_PATH"
|
|
|
- lib.defaultValue = "/usr/local/lib:/usr/lib"
|
|
|
+ case "darwin":
|
|
|
+ // On macOS, DYLD_LIBRARY_PATH is often not set, so
|
|
|
+ // we use the directory of the executable as the default.
|
|
|
+ name = "DYLD_LIBRARY_PATH"
|
|
|
+ value = filepath.Dir(exe)
|
|
|
case "windows":
|
|
|
- lib.name = "PATH"
|
|
|
- lib.defaultValue = "."
|
|
|
+ name = "PATH"
|
|
|
+ value = filepath.Join(filepath.Dir(exe), "lib", "ollama")
|
|
|
default:
|
|
|
- return
|
|
|
+ name = "LD_LIBRARY_PATH"
|
|
|
+ value = filepath.Join(filepath.Dir(exe), "..", "lib", "ollama")
|
|
|
}
|
|
|
|
|
|
- paths, ok := os.LookupEnv(lib.name)
|
|
|
+ paths, ok := os.LookupEnv(name)
|
|
|
if !ok {
|
|
|
- paths = lib.defaultValue
|
|
|
- }
|
|
|
-
|
|
|
- if runtime.GOOS == "darwin" {
|
|
|
- if _, ok := os.LookupEnv("DYLD_LIBRARY_PATH"); !ok {
|
|
|
- os.Setenv("DYLD_LIBRARY_PATH", paths)
|
|
|
- }
|
|
|
+ paths = value
|
|
|
}
|
|
|
|
|
|
split := filepath.SplitList(paths)
|
|
|
visited := make(map[string]struct{}, len(split))
|
|
|
for _, path := range split {
|
|
|
- abspath, _ := filepath.Abs(path)
|
|
|
+ abspath, err := filepath.Abs(path)
|
|
|
+ if err != nil {
|
|
|
+ slog.Error("failed to get absolute path", "error", err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
if _, ok := visited[abspath]; !ok {
|
|
|
func() {
|
|
|
- cpath := C.CString(path)
|
|
|
+ slog.Debug("ggml backend load all from path", "path", abspath)
|
|
|
+ cpath := C.CString(abspath)
|
|
|
defer C.free(unsafe.Pointer(cpath))
|
|
|
C.ggml_backend_load_all_from_path(cpath)
|
|
|
}()
|