@@ -297,6 +297,8 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc<Executor>) -> CargoResult<Work
297297 exec. init ( cx) ;
298298 let exec = exec. clone ( ) ;
299299
300+ let root_output = cx. target_root ( ) . to_path_buf ( ) ;
301+
300302 return Ok ( Work :: new ( move |state| {
301303 // Only at runtime have we discovered what the extra -L and -l
302304 // arguments are for native libraries, so we process those here. We
@@ -307,7 +309,8 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc<Executor>) -> CargoResult<Work
307309 let build_state = build_state. outputs . lock ( ) . unwrap ( ) ;
308310 add_native_deps ( & mut rustc, & build_state, & build_deps,
309311 pass_l_flag, & current_id) ?;
310- add_plugin_deps ( & mut rustc, & build_state, & build_deps) ?;
312+ add_plugin_deps ( & mut rustc, & build_state, & build_deps,
313+ & root_output) ?;
311314 }
312315
313316 // FIXME(rust-lang/rust#18913): we probably shouldn't have to do
@@ -492,7 +495,8 @@ fn load_build_deps(cx: &Context, unit: &Unit) -> Option<Arc<BuildScripts>> {
492495// execute.
493496fn add_plugin_deps ( rustc : & mut ProcessBuilder ,
494497 build_state : & BuildMap ,
495- build_scripts : & BuildScripts )
498+ build_scripts : & BuildScripts ,
499+ root_output : & PathBuf )
496500 -> CargoResult < ( ) > {
497501 let var = util:: dylib_path_envvar ( ) ;
498502 let search_path = rustc. get_env ( var) . unwrap_or ( OsString :: new ( ) ) ;
@@ -502,15 +506,47 @@ fn add_plugin_deps(rustc: &mut ProcessBuilder,
502506 let output = build_state. get ( & key) . chain_error ( || {
503507 internal ( format ! ( "couldn't find libs for plugin dep {}" , id) )
504508 } ) ?;
505- for path in output. library_paths . iter ( ) {
506- search_path. push ( path. clone ( ) ) ;
507- }
509+ search_path. append ( & mut filter_dynamic_search_path ( output. library_paths . iter ( ) ,
510+ root_output) ) ;
508511 }
509512 let search_path = join_paths ( & search_path, var) ?;
510513 rustc. env ( var, & search_path) ;
511514 Ok ( ( ) )
512515}
513516
517+ // Determine paths to add to the dynamic search path from -L entries
518+ //
519+ // Strip off prefixes like "native=" or "framework=" and filter out directories
520+ // *not* inside our output directory since they are likely spurious and can cause
521+ // clashes with system shared libraries (issue #3366).
522+ fn filter_dynamic_search_path < ' a , I > ( paths : I , root_output : & PathBuf ) -> Vec < PathBuf >
523+ where I : Iterator < Item =& ' a PathBuf > {
524+ let mut search_path = vec ! [ ] ;
525+ for dir in paths {
526+ let dir = match dir. to_str ( ) {
527+ Some ( s) => {
528+ let mut parts = s. splitn ( 2 , '=' ) ;
529+ match ( parts. next ( ) , parts. next ( ) ) {
530+ ( Some ( "native" ) , Some ( path) ) |
531+ ( Some ( "crate" ) , Some ( path) ) |
532+ ( Some ( "dependency" ) , Some ( path) ) |
533+ ( Some ( "framework" ) , Some ( path) ) |
534+ ( Some ( "all" ) , Some ( path) ) => path. into ( ) ,
535+ _ => dir. clone ( ) ,
536+ }
537+ }
538+ None => dir. clone ( ) ,
539+ } ;
540+ if dir. starts_with ( & root_output) {
541+ search_path. push ( dir) ;
542+ } else {
543+ debug ! ( "Not including path {} in runtime library search path because it is \
544+ outside target root {}", dir. display( ) , root_output. display( ) ) ;
545+ }
546+ }
547+ search_path
548+ }
549+
514550fn prepare_rustc ( cx : & mut Context ,
515551 crate_types : Vec < & str > ,
516552 unit : & Unit ) -> CargoResult < ProcessBuilder > {
0 commit comments