@@ -99,30 +99,58 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
99
99
lib. pop ( ) ;
100
100
let mut output = ( config. realpath ) ( & cwd. join ( & config. out_filename ) ) . unwrap ( ) ;
101
101
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) ) ;
103
104
// FIXME (#9639): This needs to handle non-utf8 paths
104
105
format ! ( "{}/{}" , prefix,
105
106
relative. to_str( ) . expect( "non-utf8 component in path" ) )
106
107
}
107
108
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
116
121
}
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 ( ) )
117
150
}
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
-
124
151
}
125
152
153
+
126
154
fn get_install_prefix_rpath ( config : & mut RPathConfig ) -> String {
127
155
let path = ( config. get_install_prefix_lib_path ) ( ) ;
128
156
let path = env:: current_dir ( ) . unwrap ( ) . join ( & path) ;
0 commit comments