@@ -688,13 +688,27 @@ int llamafile_makedirs(const char *path, int mode) {
688688 return mkdir (tmp , mode );
689689}
690690
691+ // Probe `path`, and if it exists, hand it to link_fn. Logs both the probe
692+ // and the success at INFO level. Returns true only if link_fn loaded it.
693+ static bool try_link_dso_from (const char * path , const char * backend_name ,
694+ const char * location , llamafile_link_dso_fn link_fn ) {
695+ if (!llamafile_file_exists (path ))
696+ return false;
697+ llamafile_info (backend_name , "probing library %s (%s)" , path , location );
698+ if (!link_fn (path ))
699+ return false;
700+ llamafile_info (backend_name , "loaded library %s from %s" , path , location );
701+ return true;
702+ }
703+
691704/**
692705 * Try to load a prebuilt DSO from standard locations.
693706 *
694707 * Search order:
695- * 1. /zip/<name> (bundled in executable, extracted to app dir)
696- * 2. ~/.llamafile/v/<version>/<name> (app directory)
697- * 3. ~/<name> (home directory)
708+ * 1. <exe_dir>/<name> (next to the llamafile executable)
709+ * 2. /zip/<name> (bundled in executable, extracted to app dir)
710+ * 3. ~/.llamafile/v/<version>/<name> (app directory)
711+ * 4. ~/<name> (home directory)
698712 *
699713 * Returns true if link_fn successfully loaded the DSO.
700714 */
@@ -703,10 +717,27 @@ bool llamafile_try_load_prebuilt_dso(const char *name, const char *backend_name,
703717 char dso [PATH_MAX ];
704718 char app_dir [PATH_MAX ];
705719
706- // Try loading from /zip/ (bundled in executable)
720+ // Try loading from the directory containing the executable. This lets
721+ // users drop a custom DSO next to the llamafile binary and have it take
722+ // precedence over the bundled and home-directory copies.
723+ const char * exe = GetProgramExecutableName ();
724+ if (exe && * exe ) {
725+ const char * slash = strrchr (exe , '/' );
726+ if (slash && slash > exe ) {
727+ size_t dir_len = (size_t )(slash - exe ) + 1 ; // include trailing '/'
728+ if (dir_len + strlen (name ) < PATH_MAX ) {
729+ memcpy (dso , exe , dir_len );
730+ memcpy (dso + dir_len , name , strlen (name ) + 1 );
731+ if (try_link_dso_from (dso , backend_name , "executable directory" , link_fn ))
732+ return true;
733+ }
734+ }
735+ }
736+
737+ // Try loading from /zip/ (bundled in executable). cosmo_dlopen can't load
738+ // from /zip/, so we extract to the app dir first and link from there.
707739 snprintf (dso , PATH_MAX , "/zip/%s" , name );
708740 if (llamafile_file_exists (dso )) {
709- // Extract to app dir first (cosmo_dlopen can't load from /zip/)
710741 llamafile_get_app_dir (app_dir , PATH_MAX );
711742 if (llamafile_makedirs (app_dir , 0755 ) != 0 ) {
712743 perror (app_dir );
@@ -717,49 +748,32 @@ bool llamafile_try_load_prebuilt_dso(const char *name, const char *backend_name,
717748 fprintf (stderr , "%s: path too long: %s%s\n" , backend_name , app_dir , name );
718749 return false;
719750 }
720- // Check if extraction needed
721751 switch (llamafile_is_file_newer_than (dso , extracted )) {
722752 case -1 :
723753 return false;
724754 case 0 :
725- // Already extracted and up to date
726755 break ;
727756 case 1 :
728- if (!llamafile_extract (dso , extracted )) {
757+ if (!llamafile_extract (dso , extracted ))
729758 return false;
730- }
731759 break ;
732760 }
733-
734- llamafile_info (backend_name , "probing library %s (bundled)" , extracted );
735- if (link_fn (extracted )) {
736- llamafile_info (backend_name , "loaded bundled library %s" , extracted );
761+ if (try_link_dso_from (extracted , backend_name , "bundled" , link_fn ))
737762 return true;
738- }
739763 }
740764
741765 // Try loading from app directory
742766 llamafile_get_app_dir (app_dir , PATH_MAX );
743767 snprintf (dso , PATH_MAX , "%s%s" , app_dir , name );
744- if (llamafile_file_exists (dso )) {
745- llamafile_info (backend_name , "probing library %s (app directory)" , dso );
746- if (link_fn (dso )) {
747- llamafile_info (backend_name , "loaded library %s from app directory" , dso );
748- return true;
749- }
750- }
768+ if (try_link_dso_from (dso , backend_name , "app directory" , link_fn ))
769+ return true;
751770
752771 // Try loading from home directory (common build location)
753772 const char * home = getenv ("HOME" );
754773 if (home && * home ) {
755774 snprintf (dso , PATH_MAX , "%s/%s" , home , name );
756- if (llamafile_file_exists (dso )) {
757- llamafile_info (backend_name , "probing library %s (home directory)" , dso );
758- if (link_fn (dso )) {
759- llamafile_info (backend_name , "loaded library %s from home directory" , dso );
760- return true;
761- }
762- }
775+ if (try_link_dso_from (dso , backend_name , "home directory" , link_fn ))
776+ return true;
763777 }
764778
765779 return false;
0 commit comments