about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-05-08 22:37:49 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-05-12 11:06:11 -0700
commitf1ab6648fc67ff8af274d2e65a400de9af0e9ddf (patch)
tree27f06f28bd15903946b1a343be12dce95957f3f7
parent7132092ce6e954eb58d490fa886d0865c5cfba38 (diff)
rustc_back: Only use archive member filenames
I've been working with some archives generated by MSVC's `lib.exe` tool lately,
and it looks like the embedded name of the members in those archives sometimes
have slahes in the name (e.g. `foo/bar/baz.obj`). Currently the compiler chokes
on these paths as it assumes that each file in the archive is only the filename
(which is what unix does).

This commit interprets the name of each file in all archives as a path and then
only uses the `file_name` portion of the path to extract the file to a separate
location and then reassemble it back into a new archive later. Note that
duplicate filenames are already handled, so this won't introduce any conflicts.
-rw-r--r--src/librustc_back/archive.rs15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs
index 37d784692fd..cad1522ee13 100644
--- a/src/librustc_back/archive.rs
+++ b/src/librustc_back/archive.rs
@@ -306,6 +306,21 @@ impl<'a> ArchiveBuilder<'a> {
             if filename.contains(".SYMDEF") { continue }
             if skip(filename) { continue }
 
+            // Archives on unix systems typically do not have slashes in
+            // filenames as the `ar` utility generally only uses the last
+            // component of a path for the filename list in the archive. On
+            // Windows, however, archives assembled with `lib.exe` will preserve
+            // the full path to the file that was placed in the archive,
+            // including path separators.
+            //
+            // The code below is munging paths so it'll go wrong pretty quickly
+            // if there's some unexpected slashes in the filename, so here we
+            // just chop off everything but the filename component. Note that
+            // this can cause duplicate filenames, but that's also handled below
+            // as well.
+            let filename = Path::new(filename).file_name().unwrap()
+                                              .to_str().unwrap();
+
             // An archive can contain files of the same name multiple times, so
             // we need to be sure to not have them overwrite one another when we
             // extract them. Consequently we need to find a truly unique file