]> git.lizzy.rs Git - rust.git/commitdiff
Copy dylib to temp directory
authorEdwin Cheng <edwin0cheng@gmail.com>
Sat, 25 Apr 2020 04:29:49 +0000 (12:29 +0800)
committerEdwin Cheng <edwin0cheng@gmail.com>
Sun, 26 Apr 2020 09:17:37 +0000 (17:17 +0800)
crates/ra_proc_macro_srv/src/dylib.rs

index 476bc5c01422374fb88a7c6db67aa7054e9ce101..018cc7bb80758b4cb731b926334291fafbb97020 100644 (file)
@@ -2,7 +2,7 @@
 
 use crate::{proc_macro::bridge, rustc_server::TokenStream};
 use std::fs::File;
-use std::path::Path;
+use std::path::{Path, PathBuf};
 
 use goblin::{mach::Mach, Object};
 use libloading::Library;
@@ -123,6 +123,9 @@ pub fn new(lib: &Path) -> Result<Expander, String> {
             .canonicalize()
             .unwrap_or_else(|err| panic!("Cannot canonicalize {}: {:?}", lib.display(), err));
 
+        // Copy the dylib to temp directory to prevent locking in Windows
+        let lib = copy_to_temp_dir(&lib).map_err(|e| e.to_string())?;
+
         let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?;
 
         Ok(Expander { inner: library })
@@ -195,3 +198,17 @@ pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
             .collect()
     }
 }
+
+fn copy_to_temp_dir(path: &Path) -> io::Result<PathBuf> {
+    let mut to = std::env::temp_dir();
+    let file_name = path.file_name().ok_or_else(|| {
+        io::Error::new(
+            io::ErrorKind::InvalidInput,
+            format!("File path is invalid: {}", path.display()),
+        )
+    })?;
+
+    to.push(file_name);
+    std::fs::copy(path, &to)?;
+    Ok(to)
+}