9
9
import sys
10
10
import typing
11
11
12
+ from itertools import chain
13
+
12
14
13
15
if typing .TYPE_CHECKING :
14
- from typing import List
16
+ from typing import List , Optional , TypeVar
15
17
16
18
from mesonpy ._compat import Iterable , Path
17
19
20
+ T = TypeVar ('T' )
21
+
22
+
23
+ def unique (values : List [T ]) -> List [T ]:
24
+ r = []
25
+ for value in values :
26
+ if value not in r :
27
+ r .append (value )
28
+ return r
29
+
18
30
19
31
if sys .platform == 'win32' or sys .platform == 'cygwin' :
20
32
21
- def fix_rpath (filepath : Path , libs_relative_path : str ) -> None :
33
+ def fix_rpath (filepath : Path , install_rpath : Optional [ str ], libs_rpath : Optional [ str ] ) -> None :
22
34
pass
23
35
24
36
elif sys .platform == 'darwin' :
@@ -35,13 +47,33 @@ def _get_rpath(filepath: Path) -> List[str]:
35
47
rpath_tag = False
36
48
return rpath
37
49
38
- def _replace_rpath (filepath : Path , old : str , new : str ) -> None :
39
- subprocess .run (['install_name_tool' , '-rpath' , old , new , os .fspath (filepath )], check = True )
50
+ def _delete_rpath (filepath : Path , rpath : Iterable [str ]) -> None :
51
+ args = list (chain (* (('-delete_rpath' , path ) for path in rpath )))
52
+ if not args :
53
+ return
54
+ subprocess .run (['install_name_tool' , * args , os .fspath (filepath )], check = True )
40
55
41
- def fix_rpath (filepath : Path , libs_relative_path : str ) -> None :
42
- for path in _get_rpath (filepath ):
43
- if path .startswith ('@loader_path/' ):
44
- _replace_rpath (filepath , path , '@loader_path/' + libs_relative_path )
56
+ def _add_rpath (filepath : Path , rpath : Iterable [str ]) -> None :
57
+ args = list (chain (* (('-add_rpath' , path ) for path in rpath )))
58
+ if not args :
59
+ return
60
+ subprocess .run (['install_name_tool' , * args , os .fspath (filepath )], check = True )
61
+
62
+ def fix_rpath (filepath : Path , install_rpath : Optional [str ], libs_rpath : Optional [str ]) -> None :
63
+ old_rpath = _get_rpath (filepath )
64
+ new_rpath = []
65
+ if libs_rpath is not None :
66
+ if libs_rpath == '.' :
67
+ libs_rpath = ''
68
+ for path in old_rpath :
69
+ if path .startswith ('@loader_path/' ):
70
+ new_rpath .append ('@loader_path/' + libs_rpath )
71
+ if install_rpath :
72
+ new_rpath .append (install_rpath )
73
+ new_rpath = unique (new_rpath )
74
+ if new_rpath != old_rpath :
75
+ _delete_rpath (filepath , old_rpath )
76
+ _add_rpath (filepath , new_rpath )
45
77
46
78
elif sys .platform == 'sunos5' :
47
79
@@ -59,13 +91,18 @@ def _get_rpath(filepath: Path) -> List[str]:
59
91
def _set_rpath (filepath : Path , rpath : Iterable [str ]) -> None :
60
92
subprocess .run (['/usr/bin/elfedit' , '-e' , 'dyn:rpath ' + ':' .join (rpath ), os .fspath (filepath )], check = True )
61
93
62
- def fix_rpath (filepath : Path , libs_relative_path : str ) -> None :
94
+ def fix_rpath (filepath : Path , install_rpath : Optional [ str ], libs_rpath : Optional [ str ] ) -> None :
63
95
old_rpath = _get_rpath (filepath )
64
96
new_rpath = []
65
- for path in old_rpath :
66
- if path .startswith ('$ORIGIN/' ):
67
- path = '$ORIGIN/' + libs_relative_path
68
- new_rpath .append (path )
97
+ if libs_rpath is not None :
98
+ if libs_rpath == '.' :
99
+ libs_rpath = ''
100
+ for path in old_rpath :
101
+ if path .startswith ('$ORIGIN/' ):
102
+ new_rpath .append ('$ORIGIN/' + libs_rpath )
103
+ if install_rpath :
104
+ new_rpath .append (install_rpath )
105
+ new_rpath = unique (new_rpath )
69
106
if new_rpath != old_rpath :
70
107
_set_rpath (filepath , new_rpath )
71
108
@@ -79,12 +116,17 @@ def _get_rpath(filepath: Path) -> List[str]:
79
116
def _set_rpath (filepath : Path , rpath : Iterable [str ]) -> None :
80
117
subprocess .run (['patchelf' ,'--set-rpath' , ':' .join (rpath ), os .fspath (filepath )], check = True )
81
118
82
- def fix_rpath (filepath : Path , libs_relative_path : str ) -> None :
119
+ def fix_rpath (filepath : Path , install_rpath : Optional [ str ], libs_rpath : Optional [ str ] ) -> None :
83
120
old_rpath = _get_rpath (filepath )
84
121
new_rpath = []
85
- for path in old_rpath :
86
- if path .startswith ('$ORIGIN/' ):
87
- path = '$ORIGIN/' + libs_relative_path
88
- new_rpath .append (path )
122
+ if libs_rpath is not None :
123
+ if libs_rpath == '.' :
124
+ libs_rpath = ''
125
+ for path in old_rpath :
126
+ if path .startswith ('$ORIGIN/' ):
127
+ new_rpath .append ('$ORIGIN/' + libs_rpath )
128
+ if install_rpath :
129
+ new_rpath .append (install_rpath )
130
+ new_rpath = unique (new_rpath )
89
131
if new_rpath != old_rpath :
90
132
_set_rpath (filepath , new_rpath )
0 commit comments