]> git.lizzy.rs Git - rust.git/commitdiff
Properly canonicalize crate paths specified via --extern
authorBjörn Steinbrink <bsteinbr@gmail.com>
Thu, 14 Aug 2014 21:42:37 +0000 (23:42 +0200)
committerBjörn Steinbrink <bsteinbr@gmail.com>
Fri, 15 Aug 2014 12:40:09 +0000 (14:40 +0200)
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

src/librustc/metadata/creader.rs
src/librustc/metadata/loader.rs
src/test/run-make/symlinked-extern/Makefile [new file with mode: 0644]
src/test/run-make/symlinked-extern/bar.rs [new file with mode: 0644]
src/test/run-make/symlinked-extern/baz.rs [new file with mode: 0644]
src/test/run-make/symlinked-extern/foo.rs [new file with mode: 0644]

index 0445b4d4e9e1f2f239a56f21c425c169ddd80ef7..321eee3d5fcefa664df18b69c24e79208ecbcfb8 100644 (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 {
index d2e1fca0da75d3cc7c4bec3fc28d05ea21789ab7..58e9e2e61d42d1011d0932e0a5e043168f139589 100644 (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());
             }
         }
 
diff --git a/src/test/run-make/symlinked-extern/Makefile b/src/test/run-make/symlinked-extern/Makefile
new file mode 100644 (file)
index 0000000..88dbad5
--- /dev/null
@@ -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
diff --git a/src/test/run-make/symlinked-extern/bar.rs b/src/test/run-make/symlinked-extern/bar.rs
new file mode 100644 (file)
index 0000000..79103f2
--- /dev/null
@@ -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) {
+}
diff --git a/src/test/run-make/symlinked-extern/baz.rs b/src/test/run-make/symlinked-extern/baz.rs
new file mode 100644 (file)
index 0000000..0f6ba25
--- /dev/null
@@ -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());
+}
diff --git a/src/test/run-make/symlinked-extern/foo.rs b/src/test/run-make/symlinked-extern/foo.rs
new file mode 100644 (file)
index 0000000..0b8bb64
--- /dev/null
@@ -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 }