1313#include < sstream>
1414#include < string>
1515
16+ #include < dlfcn.h>
17+ #include < unistd.h>
18+ #include < dirent.h>
19+
20+ #include < vector>
21+ #include < fstream>
22+ #include < sys/stat.h>
23+ // Helper to split a colon-separated path string
24+ static std::vector<std::string> splitPaths (const std::string& paths) {
25+ std::vector<std::string> result;
26+ std::stringstream ss (paths);
27+ std::string item;
28+ while (std::getline (ss, item, ' :' )) {
29+ if (!item.empty ()) result.push_back (item);
30+ }
31+ return result;
32+ }
33+
34+ // Helper to check if a file exists and is readable
35+ static bool fileExistsReadable (const std::string& path) {
36+ struct stat sb;
37+ return (stat (path.c_str (), &sb) == 0 ) && (access (path.c_str (), R_OK) == 0 );
38+ }
39+
40+ // Helper to get all library search paths from LD_LIBRARY_PATH, standard locations, and /etc/ld.so.conf
41+ static std::vector<std::string> getLibrarySearchPaths () {
42+ std::vector<std::string> paths;
43+ // LD_LIBRARY_PATH
44+ const char * ldLibPath = getenv (" LD_LIBRARY_PATH" );
45+ if (ldLibPath) {
46+ auto split = splitPaths (ldLibPath);
47+ paths.insert (paths.end (), split.begin (), split.end ());
48+ }
49+ // Standard locations
50+ paths.push_back (" /lib" );
51+ paths.push_back (" /usr/lib" );
52+ paths.push_back (" /usr/local/lib" );
53+ // /etc/ld.so.conf and included files
54+ std::ifstream ldSoConf (" /etc/ld.so.conf" );
55+ if (ldSoConf) {
56+ std::string line;
57+ while (std::getline (ldSoConf, line)) {
58+ if (line.empty ()) continue ;
59+ if (line.find (" include " ) == 0 ) {
60+ std::string pattern = line.substr (8 );
61+ // Simple glob: /etc/ld.so.conf.d/*.conf
62+ std::string dir = pattern.substr (0 , pattern.find_last_of (' /' ));
63+ std::string ext = pattern.substr (pattern.find_last_of (' .' ));
64+ DIR* d = opendir (dir.c_str ());
65+ if (d) {
66+ struct dirent * ent;
67+ while ((ent = readdir (d)) != nullptr ) {
68+ std::string fname = ent->d_name ;
69+ if (fname.size () > ext.size () && fname.substr (fname.size ()-ext.size ()) == ext) {
70+ std::ifstream incFile (dir + " /" + fname);
71+ std::string incLine;
72+ while (std::getline (incFile, incLine)) {
73+ if (!incLine.empty () && incLine[0 ] != ' #' )
74+ paths.push_back (incLine);
75+ }
76+ }
77+ }
78+ closedir (d);
79+ }
80+ } else if (line[0 ] != ' #' ) {
81+ paths.push_back (line);
82+ }
83+ }
84+ }
85+ return paths;
86+ }
87+
88+ // Main function: search for a library file in all known library paths
89+ static bool libraryExistsInSearchPaths (const std::string& filename) {
90+ auto paths = getLibrarySearchPaths ();
91+ for (const auto & dir : paths) {
92+ std::string fullPath = dir + " /" + filename;
93+ if (fileExistsReadable (fullPath)) {
94+ return true ;
95+ }
96+ }
97+ return false ;
98+ }
99+
16100namespace loader {
17101
18102static const char *knownDriverNames[] = {
@@ -30,7 +114,9 @@ std::vector<DriverLibraryPath> discoverEnabledDrivers() {
30114 altDrivers = getenv (" ZE_ENABLE_ALT_DRIVERS" );
31115 if (altDrivers == nullptr ) {
32116 for (auto path : knownDriverNames) {
33- enabledDrivers.emplace_back (path);
117+ if (libraryExistsInSearchPaths (path)) {
118+ enabledDrivers.emplace_back (path);
119+ }
34120 }
35121 } else {
36122 std::stringstream ss (altDrivers);
0 commit comments