99import sys
1010import typing
1111
12+ from itertools import chain
13+
1214
1315if typing .TYPE_CHECKING :
14- from typing import List
16+ from typing import List , TypeVar
1517
1618 from mesonpy ._compat import Iterable , Path
1719
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+
1830
1931if sys .platform == 'win32' or sys .platform == 'cygwin' :
2032
21- def fix_rpath (filepath : Path , libs_relative_path : str ) -> None :
33+ def fix_rpath (filepath : Path , rpath : List [ str ] ) -> None :
2234 pass
2335
2436elif sys .platform == 'darwin' :
@@ -35,13 +47,27 @@ def _get_rpath(filepath: Path) -> List[str]:
3547 rpath_tag = False
3648 return rpath
3749
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 , paths : List [str ]) -> None :
51+ args = chain (* (('-delete_rpath' , path ) for path in paths ))
52+ subprocess .run (['install_name_tool' , * args , os .fspath (filepath )], check = True )
4053
54+ def _add_rpath (filepath : Path , paths : List [str ]) -> None :
55+ args = chain (* (('-add_rpath' , path ) for path in paths ))
56+ subprocess .run (['install_name_tool' , * args , os .fspath (filepath )], check = True )
57+
4158 def fix_rpath (filepath : Path , libs_relative_path : str ) -> None :
42- for path in _get_rpath (filepath ):
59+ old_rpath = _get_rpath (filepath )
60+ new_rpath = []
61+ for path in old_rpath :
4362 if path .startswith ('@loader_path/' ):
44- _replace_rpath (filepath , path , '@loader_path/' + libs_relative_path )
63+ path = '$ORIGIN/' + libs_relative_path
64+ new_rpath .append (path )
65+ if rpath :
66+ new_rpath .extend (rpath )
67+ new_rpath = unique (rpath )
68+ if new_rpath != old_rpath :
69+ _delete_rpath (old_rpath )
70+ _add_rpath (new_rpath )
4571
4672elif sys .platform == 'sunos5' :
4773
@@ -59,13 +85,16 @@ def _get_rpath(filepath: Path) -> List[str]:
5985 def _set_rpath (filepath : Path , rpath : Iterable [str ]) -> None :
6086 subprocess .run (['/usr/bin/elfedit' , '-e' , 'dyn:rpath ' + ':' .join (rpath ), os .fspath (filepath )], check = True )
6187
62- def fix_rpath (filepath : Path , libs_relative_path : str ) -> None :
88+ def fix_rpath (filepath : Path , rpath : str ) -> None :
6389 old_rpath = _get_rpath (filepath )
6490 new_rpath = []
6591 for path in old_rpath :
6692 if path .startswith ('$ORIGIN/' ):
6793 path = '$ORIGIN/' + libs_relative_path
6894 new_rpath .append (path )
95+ if rpath :
96+ new_rpath .extend (rpath )
97+ new_rpath = unique (rpath )
6998 if new_rpath != old_rpath :
7099 _set_rpath (filepath , new_rpath )
71100
@@ -79,12 +108,15 @@ def _get_rpath(filepath: Path) -> List[str]:
79108 def _set_rpath (filepath : Path , rpath : Iterable [str ]) -> None :
80109 subprocess .run (['patchelf' ,'--set-rpath' , ':' .join (rpath ), os .fspath (filepath )], check = True )
81110
82- def fix_rpath (filepath : Path , libs_relative_path : str ) -> None :
111+ def fix_rpath (filepath : Path , rpath : str ) -> None :
83112 old_rpath = _get_rpath (filepath )
84113 new_rpath = []
85114 for path in old_rpath :
86115 if path .startswith ('$ORIGIN/' ):
87116 path = '$ORIGIN/' + libs_relative_path
88117 new_rpath .append (path )
118+ if rpath :
119+ new_rpath .extend (rpath )
120+ new_rpath = unique (rpath )
89121 if new_rpath != old_rpath :
90122 _set_rpath (filepath , new_rpath )
0 commit comments