Skip to content

Commit

Permalink
Properly canonicalize crate paths specified via --extern
Browse files Browse the repository at this point in the history
Crates that are resolved normally have their path canonicalized and all
symlinks resolved. This does currently not happen for paths specified
using the --extern option to rustc, which can lead to rustc thinking
that it encountered two different versions of a crate, when it's
actually the same version found through different paths.

To fix this, we must store the canonical path for crates found via
--extern and also use the canonical path when comparing paths.

Fixes rust-lang#16496
  • Loading branch information
dotdash committed Aug 15, 2014
1 parent a8c8e3f commit a5590b3
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/librustc/metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use syntax::diagnostic::SpanHandler;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::visit;
use util::fs;

struct Env<'a> {
sess: &'a Session,
Expand Down Expand Up @@ -301,7 +302,7 @@ fn existing_match(e: &Env, name: &str,
match e.sess.opts.externs.find_equiv(&name) {
Some(locs) => {
let found = locs.iter().any(|l| {
let l = Some(Path::new(l.as_slice()));
let l = fs::realpath(&Path::new(l.as_slice())).ok();
l == source.dylib || l == source.rlib
});
if found {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/metadata/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,9 +666,9 @@ impl<'a> Context<'a> {
let mut dylibs = HashSet::new();
for loc in locs {
if loc.filename_str().unwrap().ends_with(".rlib") {
rlibs.insert(loc.clone());
rlibs.insert(fs::realpath(&loc).unwrap());
} else {
dylibs.insert(loc.clone());
dylibs.insert(fs::realpath(&loc).unwrap());
}
}

Expand Down
16 changes: 16 additions & 0 deletions src/test/run-make/symlinked-extern/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-include ../tools.mk

# ignore windows: `ln` is actually `cp` on msys.
ifndef IS_WINDOWS

all:
$(RUSTC) foo.rs
mkdir -p $(TMPDIR)/other
ln -nsf $(TMPDIR)/libfoo.rlib $(TMPDIR)/other
$(RUSTC) bar.rs -L $(TMPDIR)
$(RUSTC) baz.rs --extern foo=$(TMPDIR)/other/libfoo.rlib -L $(TMPDIR)

else
all:

endif
16 changes: 16 additions & 0 deletions src/test/run-make/symlinked-extern/bar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_type = "rlib"]

extern crate foo;

pub fn bar(_s: foo::S) {
}
16 changes: 16 additions & 0 deletions src/test/run-make/symlinked-extern/baz.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate bar;
extern crate foo;

fn main() {
bar::bar(foo::foo());
}
15 changes: 15 additions & 0 deletions src/test/run-make/symlinked-extern/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_type = "rlib"]

pub struct S;

pub fn foo() -> S { S }

1 comment on commit a5590b3

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+

Please sign in to comment.