about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPetr Hosek <phosek@google.com>2019-07-01 17:28:10 -0700
committerPetr Hosek <phosek@google.com>2019-07-02 00:42:56 -0700
commit069c52fa111e592f65605c54f5e9b77be0676595 (patch)
treeeea32d8b1d1c934c4517420c8bb76366523526c1
parent17e62f77f954bed97aae839624bfd6dd68342daf (diff)
downloadrust-069c52fa111e592f65605c54f5e9b77be0676595.tar.gz
rust-069c52fa111e592f65605c54f5e9b77be0676595.zip
Check if the archive has already been added to avoid duplicates
This avoids adding archives multiple times, which results in duplicate
objects in the resulting rlib, leading to symbol collision and link
failures. This could happen when crate contains multiple link attributes
that all reference the same archive.
-rw-r--r--src/librustc_codegen_llvm/back/archive.rs19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs
index e0e26e9af25..90c0cf748d1 100644
--- a/src/librustc_codegen_llvm/back/archive.rs
+++ b/src/librustc_codegen_llvm/back/archive.rs
@@ -36,11 +36,20 @@ enum Addition {
         name_in_archive: String,
     },
     Archive {
+        path: PathBuf,
         archive: ArchiveRO,
         skip: Box<dyn FnMut(&str) -> bool>,
     },
 }
 
+impl Addition {
+    fn path(&self) -> &Path {
+        match self {
+            Addition::File { path, .. } | Addition::Archive { path, .. } => path,
+        }
+    }
+}
+
 fn is_relevant_child(c: &Child<'_>) -> bool {
     match c.name() {
         Some(name) => !name.contains("SYMDEF"),
@@ -188,12 +197,16 @@ impl<'a> LlvmArchiveBuilder<'a> {
                       -> io::Result<()>
         where F: FnMut(&str) -> bool + 'static
     {
-        let archive = match ArchiveRO::open(archive) {
+        let archive_ro = match ArchiveRO::open(archive) {
             Ok(ar) => ar,
             Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
         };
+        if self.additions.iter().any(|ar| ar.path() == archive) {
+            return Ok(())
+        }
         self.additions.push(Addition::Archive {
-            archive,
+            path: archive.to_path_buf(),
+            archive: archive_ro,
             skip: Box::new(skip),
         });
         Ok(())
@@ -243,7 +256,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
                         strings.push(path);
                         strings.push(name);
                     }
-                    Addition::Archive { archive, skip } => {
+                    Addition::Archive { archive, skip, .. } => {
                         for child in archive.iter() {
                             let child = child.map_err(string_to_io_error)?;
                             if !is_relevant_child(&child) {