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 ,  Optional ,  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 , install_rpath :  Optional [ List [ str ]],  libs_rpath :  Optional [ str ] ) ->  None :
2234        pass 
2335
2436elif  sys .platform  ==  'darwin' :
@@ -35,13 +47,33 @@ 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 , 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 )
4055
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 [List [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 .extend (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 )
4577
4678elif  sys .platform  ==  'sunos5' :
4779
@@ -59,13 +91,18 @@ def _get_rpath(filepath: Path) -> List[str]:
5991    def  _set_rpath (filepath : Path , rpath : Iterable [str ]) ->  None :
6092        subprocess .run (['/usr/bin/elfedit' , '-e' , 'dyn:rpath '  +  ':' .join (rpath ), os .fspath (filepath )], check = True )
6193
62-     def  fix_rpath (filepath : Path , libs_relative_path :  str ) ->  None :
94+     def  fix_rpath (filepath : Path , install_rpath :  Optional [ List [ str ]],  libs_rpath :  Optional [ str ] ) ->  None :
6395        old_rpath  =  _get_rpath (filepath )
6496        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 .extend (install_rpath )
105+         new_rpath  =  unique (new_rpath )
69106        if  new_rpath  !=  old_rpath :
70107            _set_rpath (filepath , new_rpath )
71108
@@ -79,12 +116,17 @@ def _get_rpath(filepath: Path) -> List[str]:
79116    def  _set_rpath (filepath : Path , rpath : Iterable [str ]) ->  None :
80117        subprocess .run (['patchelf' ,'--set-rpath' , ':' .join (rpath ), os .fspath (filepath )], check = True )
81118
82-     def  fix_rpath (filepath : Path , libs_relative_path :  str ) ->  None :
119+     def  fix_rpath (filepath : Path , install_rpath :  Optional [ List [ str ]],  libs_rpath :  Optional [ str ] ) ->  None :
83120        old_rpath  =  _get_rpath (filepath )
84121        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 .extend (install_rpath )
130+         new_rpath  =  unique (new_rpath )
89131        if  new_rpath  !=  old_rpath :
90132            _set_rpath (filepath , new_rpath )
0 commit comments