23
23
_IS_DARWIN = sys .platform == "darwin"
24
24
25
25
26
- def _search_directories (get_config ):
26
+ def _search_directories (get_config , base_executable ):
27
27
"""Returns a list of library directories to search for shared libraries."""
28
28
# There's several types of libraries with different names and a plethora
29
29
# of settings, and many different config variables to check:
@@ -53,19 +53,23 @@ def _search_directories(get_config):
53
53
if config_value and not config_value .endswith (multiarch ):
54
54
lib_dirs .append (os .path .join (config_value , multiarch ))
55
55
56
- if _IS_WINDOWS :
57
- # On Windows DLLs go in the same directory as the executable, while .lib
58
- # files live in the lib/ or libs/ subdirectory.
59
- lib_dirs .append (get_config ("BINDIR" ))
60
- lib_dirs .append (os .path .join (os .path .dirname (sys .executable )))
61
- lib_dirs .append (os .path .join (os .path .dirname (sys .executable ), "lib" ))
62
- lib_dirs .append (os .path .join (os .path .dirname (sys .executable ), "libs" ))
63
- elif not _IS_DARWIN :
64
- # On most systems the executable is in a bin/ directory and the libraries
65
- # are in a sibling lib/ directory.
66
- lib_dirs .append (
67
- os .path .join (os .path .dirname (os .path .dirname (sys .executable )), "lib" )
68
- )
56
+ if not _IS_DARWIN :
57
+ for exec_dir in (
58
+ os .path .dirname (base_executable ) if base_executable else None ,
59
+ get_config ("BINDIR" ),
60
+ ):
61
+ if not exec_dir :
62
+ continue
63
+ if _IS_WINDOWS :
64
+ # On Windows DLLs go in the same directory as the executable, while .lib
65
+ # files live in the lib/ or libs/ subdirectory.
66
+ lib_dirs .append (exec_dir )
67
+ lib_dirs .append (os .path .join (exec_dir , "lib" ))
68
+ lib_dirs .append (os .path .join (exec_dir , "libs" ))
69
+ else :
70
+ # On most systems the executable is in a bin/ directory and the libraries
71
+ # are in a sibling lib/ directory.
72
+ lib_dirs .append (os .path .join (os .path .dirname (exec_dir ), "lib" ))
69
73
70
74
# Dedup and remove empty values, keeping the order.
71
75
lib_dirs = [v for v in lib_dirs if v ]
@@ -126,7 +130,7 @@ def _search_library_names(get_config):
126
130
return {k : None for k in lib_names }.keys ()
127
131
128
132
129
- def _get_python_library_info ():
133
+ def _get_python_library_info (base_executable ):
130
134
"""Returns a dictionary with the static and dynamic python libraries."""
131
135
config_vars = sysconfig .get_config_vars ()
132
136
@@ -140,7 +144,7 @@ def _get_python_library_info():
140
144
f"{ sys .version_info .major } .{ sys .version_info .minor } "
141
145
)
142
146
143
- search_directories = _search_directories (config_vars .get )
147
+ search_directories = _search_directories (config_vars .get , base_executable )
144
148
search_libnames = _search_library_names (config_vars .get )
145
149
146
150
def _add_if_exists (target , path ):
@@ -187,13 +191,28 @@ def _add_if_exists(target, path):
187
191
}
188
192
189
193
194
+ def _get_base_executable ():
195
+ """Returns the base executable path."""
196
+ try :
197
+ if sys ._base_executable : # pylint: disable=protected-access
198
+ return sys ._base_executable # pylint: disable=protected-access
199
+ except AttributeError :
200
+ # Bug reports indicate sys._base_executable doesn't exist in some cases,
201
+ # but it's not clear why.
202
+ # See https://github.com/bazel-contrib/rules_python/issues/3172
203
+ pass
204
+ # The normal sys.executable is the next-best guess if sys._base_executable
205
+ # is missing.
206
+ return sys .executable
207
+
208
+
190
209
data = {
191
210
"major" : sys .version_info .major ,
192
211
"minor" : sys .version_info .minor ,
193
212
"micro" : sys .version_info .micro ,
194
213
"include" : sysconfig .get_path ("include" ),
195
214
"implementation_name" : sys .implementation .name ,
196
- "base_executable" : sys . _base_executable ,
215
+ "base_executable" : _get_base_executable () ,
197
216
}
198
- data .update (_get_python_library_info ())
217
+ data .update (_get_python_library_info (_get_base_executable () ))
199
218
print (json .dumps (data ))
0 commit comments