Skip to content

Commit dab89c4

Browse files
authored
Refactor library symlinking and update template
1 parent 8dbe685 commit dab89c4

File tree

1 file changed

+57
-33
lines changed

1 file changed

+57
-33
lines changed

bazel/repo_rules/local_python_runtime.bzl

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -60,59 +60,66 @@ define_local_runtime_toolchain_impl(
6060
major = "{major}",
6161
minor = "{minor}",
6262
micro = "{micro}",
63+
abi_flags = "{abi_flags}",
64+
os = "{os}",
65+
implementation_name = "{implementation_name}",
6366
interpreter_path = "{interpreter_path}",
6467
interface_library = {interface_library},
6568
libraries = {libraries},
66-
implementation_name = "{implementation_name}",
67-
os = "{os}",
68-
abi_flags = "{abi_flags}",
69+
abi3_interface_library = {abi3_interface_library},
70+
abi3_libraries = {abi3_libraries},
6971
)
7072
"""
7173

7274
def _expand_incompatible_template():
7375
return _TOOLCHAIN_IMPL_TEMPLATE.format(
74-
interpreter_path = "/incompatible",
75-
implementation_name = "incompatible",
76-
interface_library = "None",
77-
libraries = "[]",
7876
major = "0",
7977
minor = "0",
8078
micro = "0",
81-
os = "@platforms//:incompatible",
8279
abi_flags = "",
80+
os = "@platforms//:incompatible",
81+
implementation_name = "incompatible",
82+
interpreter_path = "/incompatible",
83+
interface_library = "None",
84+
libraries = "[]",
85+
abi3_interface_library = "None",
86+
abi3_libraries = "[]",
8387
)
8488

85-
def _symlink_first_library(rctx, logger, libraries, shlib_suffix):
89+
def _symlink_libraries(rctx, logger, subdir, libraries, shlib_suffix):
8690
"""Symlinks the shared libraries into the lib/ directory.
8791
8892
Args:
8993
rctx: A repository_ctx object
9094
logger: A repo_utils.logger object
91-
libraries: A list of static library paths to potentially symlink.
95+
subdir: The subdirectory to symlink to. e.g. "lib"
96+
libraries: paths to libraries to attempt to symlink.
97+
shlib_suffix: Optional. Ensure that the generated symlinks end with this suffix.
9298
Returns:
9399
A single library path linked by the action.
94100
95-
The specific files are symlinked instead of the whole directory because
101+
Individual files are symlinked instead of the whole directory because
96102
shared_lib_dirs contains multiple search paths for the shared libraries,
97103
and the python files may be missing from any of those directories, and
98104
any of those directories may include non-python runtime libraries,
99105
as would be the case if LIBDIR were, for example, /usr/lib.
100106
"""
101-
for target in libraries:
102-
origin = rctx.path(target)
107+
result = []
108+
for source in libraries:
109+
origin = rctx.path(source)
103110
if not origin.exists:
104111
# The reported names don't always exist; it depends on the particulars
105112
# of the runtime installation.
106113
continue
107-
if shlib_suffix and not target.endswith(shlib_suffix):
108-
linked = "lib/{}{}".format(origin.basename, shlib_suffix)
114+
if shlib_suffix and not origin.basename.endswith(shlib_suffix):
115+
target = "{}/{}{}".format(subdir, origin.basename, shlib_suffix)
109116
else:
110-
linked = "lib/{}".format(origin.basename)
111-
logger.debug(lambda: "Symlinking {} to {}".format(origin, linked))
117+
target = "{}/{}".format(subdir, origin.basename)
118+
logger.debug(lambda: "Symlinking {} to {}".format(origin, target))
112119
repo_utils.watch(rctx, origin)
113-
rctx.symlink(origin, linked)
114-
return linked
115-
return None
120+
rctx.symlink(origin, target)
121+
result.append(target)
122+
return result
116123

117124
def _local_python_repo_impl(rctx):
118125
"""Implementation of the local_python_repo repository rule."""
@@ -190,28 +197,45 @@ def _local_python_repo_impl(rctx):
190197
rctx.symlink(include_path, "include")
191198

192199
rctx.report_progress("Symlinking external Python shared libraries")
193-
interface_library = _symlink_first_library(rctx, logger, info["interface_libraries"], None)
194-
shared_library = _symlink_first_library(rctx, logger, info["dynamic_libraries"], info["shlib_suffix"])
195-
static_library = _symlink_first_library(rctx, logger, info["static_libraries"], None)
196-
197-
libraries = []
198-
if shared_library:
199-
libraries.append(shared_library)
200-
elif static_library:
201-
libraries.append(static_library)
200+
201+
interface_library = None
202+
libraries = _symlink_libraries(rctx, logger, "lib", info["dynamic_libraries"], info["shlib_suffix"])
203+
if libraries:
204+
symlinked = _symlink_libraries(rctx, logger, "lib", info["interface_libraries"], None)
205+
if symlinked:
206+
interface_library = symlinked[0]
207+
else:
208+
libraries = _symlink_libraries(rctx, logger, "lib", info["static_libraries"], None)
209+
if not libraries:
210+
logger.info("No python libraries found.")
211+
212+
abi3_interface_library = None
213+
abi3_libraries = _symlink_libraries(rctx, logger, "lib", info["abi_dynamic_libraries"], info["shlib_suffix"])
214+
if abi3_libraries:
215+
symlinked = _symlink_libraries(rctx, logger, "lib", info["abi_interface_libraries"], None)
216+
if symlinked:
217+
abi3_interface_library = symlinked[0]
202218
else:
203-
logger.warn("No external python libraries found.")
219+
logger.info("No abi3 python libraries found.")
220+
221+
# On Windows, we need to link to the additional DLLs.
222+
if info["additional_dlls"]:
223+
_symlink_libraries(rctx, logger, "dlls", info["additional_dlls"], None)
224+
225+
os_name = repo_utils.get_platforms_os_name(rctx)
204226

205227
build_bazel = _TOOLCHAIN_IMPL_TEMPLATE.format(
206228
major = info["major"],
207229
minor = info["minor"],
208230
micro = info["micro"],
231+
abi_flags = info["abi_flags"],
232+
os = "@platforms//os:{}".format(os_name),
233+
implementation_name = info["implementation_name"],
209234
interpreter_path = repo_utils.norm_path(interpreter_path),
210235
interface_library = repr(interface_library),
211236
libraries = repr(libraries),
212-
implementation_name = info["implementation_name"],
213-
os = "@platforms//os:{}".format(repo_utils.get_platforms_os_name(rctx)),
214-
abi_flags = info["abi_flags"],
237+
abi3_interface_library = repr(abi3_interface_library),
238+
abi3_libraries = repr(abi3_libraries),
215239
)
216240
logger.debug(lambda: "BUILD.bazel\n{}".format(build_bazel))
217241

0 commit comments

Comments
 (0)