@@ -99,30 +99,58 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
9999 lib. pop ( ) ;
100100 let mut output = ( config. realpath ) ( & cwd. join ( & config. out_filename ) ) . unwrap ( ) ;
101101 output. pop ( ) ;
102- let relative = relativize ( & lib, & output) ;
102+ let relative = path_relative_from ( & lib, & output)
103+ . expect ( & format ! ( "couldn't create relative path from {:?} to {:?}" , output, lib) ) ;
103104 // FIXME (#9639): This needs to handle non-utf8 paths
104105 format ! ( "{}/{}" , prefix,
105106 relative. to_str( ) . expect( "non-utf8 component in path" ) )
106107}
107108
108- fn relativize ( path : & Path , rel : & Path ) -> PathBuf {
109- let mut res = PathBuf :: new ( "" ) ;
110- let mut cur = rel;
111- while !path. starts_with ( cur) {
112- res. push ( ".." ) ;
113- match cur. parent ( ) {
114- Some ( p) => cur = p,
115- None => panic ! ( "can't create relative paths across filesystems" ) ,
109+ // This routine is adapted from the *old* Path's `path_relative_from`
110+ // function, which works differently from the new `relative_from` function.
111+ // In particular, this handles the case on unix where both paths are
112+ // absolute but with only the root as the common directory.
113+ fn path_relative_from ( path : & Path , base : & Path ) -> Option < PathBuf > {
114+ use std:: path:: Component ;
115+
116+ if path. is_absolute ( ) != base. is_absolute ( ) {
117+ if path. is_absolute ( ) {
118+ Some ( PathBuf :: new ( path) )
119+ } else {
120+ None
116121 }
122+ } else {
123+ let mut ita = path. components ( ) ;
124+ let mut itb = base. components ( ) ;
125+ let mut comps: Vec < Component > = vec ! [ ] ;
126+ loop {
127+ match ( ita. next ( ) , itb. next ( ) ) {
128+ ( None , None ) => break ,
129+ ( Some ( a) , None ) => {
130+ comps. push ( a) ;
131+ comps. extend ( ita. by_ref ( ) ) ;
132+ break ;
133+ }
134+ ( None , _) => comps. push ( Component :: ParentDir ) ,
135+ ( Some ( a) , Some ( b) ) if comps. is_empty ( ) && a == b => ( ) ,
136+ ( Some ( a) , Some ( b) ) if b == Component :: CurDir => comps. push ( a) ,
137+ ( Some ( _) , Some ( b) ) if b == Component :: ParentDir => return None ,
138+ ( Some ( a) , Some ( _) ) => {
139+ comps. push ( Component :: ParentDir ) ;
140+ for _ in itb {
141+ comps. push ( Component :: ParentDir ) ;
142+ }
143+ comps. push ( a) ;
144+ comps. extend ( ita. by_ref ( ) ) ;
145+ break ;
146+ }
147+ }
148+ }
149+ Some ( comps. iter ( ) . map ( |c| c. as_os_str ( ) ) . collect ( ) )
117150 }
118- match path. relative_from ( cur) {
119- Some ( s) => { res. push ( s) ; res }
120- None => panic ! ( "couldn't create relative path from {:?} to {:?}" ,
121- rel, path) ,
122- }
123-
124151}
125152
153+
126154fn get_install_prefix_rpath ( config : & mut RPathConfig ) -> String {
127155 let path = ( config. get_install_prefix_lib_path ) ( ) ;
128156 let path = env:: current_dir ( ) . unwrap ( ) . join ( & path) ;
0 commit comments