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 #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
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
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
@@ -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
@@ -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
@@ -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
@@ -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 }

5 comments on commit a5590b3

@bors
Copy link
Contributor

@bors bors commented on a5590b3 Aug 16, 2014

Choose a reason for hiding this comment

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

saw approval from alexcrichton
at dotdash@a5590b3

@bors
Copy link
Contributor

@bors bors commented on a5590b3 Aug 16, 2014

Choose a reason for hiding this comment

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

merging dotdash/rust/extern_realpath = a5590b3 into auto

@bors
Copy link
Contributor

@bors bors commented on a5590b3 Aug 16, 2014

Choose a reason for hiding this comment

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

dotdash/rust/extern_realpath = a5590b3 merged ok, testing candidate = 17bcc1b

@bors
Copy link
Contributor

@bors bors commented on a5590b3 Aug 16, 2014

Choose a reason for hiding this comment

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

fast-forwarding master to auto = 17bcc1b

Please sign in to comment.