@@ -39,26 +39,63 @@ def get_clang_library_dirs(clang_executable_path: str) -> List[str]:
39
39
return library_dirs
40
40
41
41
42
- def get_clang_library_dir (clang_executable_path : str ) -> str :
42
+ def get_clang_library_dir (
43
+ clang_executable_path : str ,
44
+ look_for_file : Optional [str ] = None ,
45
+ all_dirs : bool = False ) -> List [str ]:
46
+ """
47
+ Finds and returns the Clang runtime library directory using the provided Clang executable path.
48
+ For each of the library directories returned by get_clang_library_dirs(), we will look for a
49
+ a lib/linux or lib/<arch>-unknown-linux-gnu subdirectory. If we find such a subdirectory, we
50
+ will consider returning it (but only if it contains the given file if specified).
51
+
52
+ :param clang_executable_path: The path to the Clang executable.
53
+ :param look_for_file: An optional file to look for in the candidate directory. If this file does
54
+ not exist in the candidate directory, we will continue looking for another
55
+ candidate directory.
56
+ :param all_dirs: to return all possible directories. This set of directories is filtered by the
57
+ presence of the look_for_file if specified.
58
+ :return: the Clang runtime library directory, or an empty list if not found, or all directories
59
+ if all_dirs is specified.
60
+ """
43
61
library_dirs = get_clang_library_dirs (clang_executable_path )
44
62
candidate_dirs : List [str ] = []
45
63
46
64
arch = platform .machine ()
47
65
arch_specific_subdir_name = f'{ arch } -unknown-linux-gnu'
66
+ subdir_names = ['linux' , arch_specific_subdir_name ]
67
+
68
+ found_dirs : List [str ] = []
48
69
49
70
for library_dir in library_dirs :
50
- for subdir_name in [ 'linux' , arch_specific_subdir_name ] :
71
+ for subdir_name in subdir_names :
51
72
candidate_dir = os .path .join (library_dir , 'lib' , subdir_name )
52
- if os .path .isdir (candidate_dir ):
53
- return candidate_dir
73
+ if os .path .isdir (candidate_dir ) and (
74
+ look_for_file is None or
75
+ os .path .exists (os .path .join (candidate_dir , look_for_file ))):
76
+ if all_dirs :
77
+ found_dirs .append (candidate_dir )
78
+ else :
79
+ # Return the first directory we found satisfying the condition.
80
+ return [candidate_dir ]
54
81
candidate_dirs .append (candidate_dir )
55
82
83
+ if (all_dirs and found_dirs ) or look_for_file is not None :
84
+ # If we are looking for all directories, return all directories we found. But make sure
85
+ # we found at least one.
86
+ #
87
+ # If we are looking for a specific file, allow returning an empty list if we did not find
88
+ # a directory with that particular file.
89
+ return found_dirs
90
+
56
91
for candidate_dir in candidate_dirs :
57
92
log (f"Considered candidate directory: { candidate_dir } " )
58
93
raise ValueError (
59
94
"Could not find the Clang runtime library directory by appending lib/... suffixes to "
60
95
"any of the directories returned by 'clang -print-search-dirs' "
61
- f"(clang path: { clang_executable_path } ): { library_dirs } " )
96
+ f"(clang path: { clang_executable_path } , subdir names: { subdir_names } , "
97
+ f"file name that must exist in the directory: { look_for_file } ): { library_dirs } "
98
+ )
62
99
63
100
64
101
def get_clang_include_dir (clang_executable_path : str ) -> str :
0 commit comments