Properly canonicalize crate paths specified via --extern

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
This commit is contained in:
Björn Steinbrink 2014-08-14 23:42:37 +02:00
parent a8c8e3f80f
commit a5590b3c75
6 changed files with 67 additions and 3 deletions

View File

@ -33,6 +33,7 @@
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::visit;
use util::fs;
struct Env<'a> {
sess: &'a Session,
@ -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 {

View File

@ -666,9 +666,9 @@ fn find_commandline_library(&mut self) -> Option<Library> {
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());
}
}

View File

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

View File

@ -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) {
}

View File

@ -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());
}

View File

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