44
55from __future__ import annotations
66
7+ import os .path
78from typing import TYPE_CHECKING
89
910import auditwheel # noqa: F401
1011
12+ from .._logging import logger
1113from . import WheelRepairer
1214
1315if TYPE_CHECKING :
16+ from pathlib import Path
17+
1418 from ..file_api .model .codemodel import Target
1519
1620__all__ = ["LinuxWheelRepairer" ]
@@ -23,6 +27,37 @@ class LinuxWheelRepairer(WheelRepairer):
2327
2428 _platform = "Linux"
2529
30+ def patch_linux_library_rpath (self , lib : Path , rpaths : list [str ]) -> None :
31+ """Patch the rpaths of a specific library."""
32+
2633 def patch_target (self , target : Target ) -> None :
27- # TODO: Implement patching
28- pass
34+ # Get the target install paths where the $ORIGIN is calculated from
35+ target_install_paths = self .get_wheel_install_paths (target )
36+ if not target_install_paths :
37+ logger .debug (
38+ "Skip patching {target} because all install paths are outside the wheel." ,
39+ target = target .name ,
40+ )
41+ return
42+ if len (set (target .artifacts )) != 1 :
43+ logger .warning (
44+ "Unexpected multiple artifacts for target {target}: {artifacts}" ,
45+ target = target .name ,
46+ artifacts = [item .path for item in target .artifacts ],
47+ )
48+ return
49+ artifact = target .artifacts [0 ]
50+ for install_path in target_install_paths :
51+ target_path = self .install_dir / install_path
52+ dependency_rpaths = []
53+ for dep_target in self .get_library_dependencies (target ):
54+ dep_install_paths = self .get_wheel_install_paths (dep_target )
55+ assert len (dep_install_paths ) == 1
56+ dep_path = self .install_dir / next (iter (dep_install_paths ))
57+ rpath = os .path .relpath (dep_path , target_path )
58+ rpath = f"$ORIGIN/{ rpath } "
59+ dependency_rpaths .append (rpath )
60+ self .patch_linux_library_rpath (
61+ lib = target_path / artifact .path ,
62+ rpaths = dependency_rpaths ,
63+ )
0 commit comments