|
3 | 3 | use std::env;
|
4 | 4 | use std::ffi::{OsStr, OsString};
|
5 | 5 | use std::fs::{self, File};
|
| 6 | +use std::io; |
6 | 7 | use std::io::prelude::*;
|
7 |
| -use std::path::PathBuf; |
| 8 | +use std::path::{Path, PathBuf}; |
8 | 9 |
|
9 | 10 | use cc;
|
10 | 11 | use tempdir::TempDir;
|
@@ -49,10 +50,13 @@ impl Test {
|
49 | 50 | }
|
50 | 51 |
|
51 | 52 | pub fn shim(&self, name: &str) -> &Test {
|
52 |
| - let fname = format!("{}{}", name, env::consts::EXE_SUFFIX); |
53 |
| - fs::hard_link(&self.gcc, self.td.path().join(&fname)) |
54 |
| - .or_else(|_| fs::copy(&self.gcc, self.td.path().join(&fname)).map(|_| ())) |
55 |
| - .unwrap(); |
| 53 | + link_or_copy( |
| 54 | + &self.gcc, |
| 55 | + self.td |
| 56 | + .path() |
| 57 | + .join(&format!("{}{}", name, env::consts::EXE_SUFFIX)), |
| 58 | + ) |
| 59 | + .unwrap(); |
56 | 60 | self
|
57 | 61 | }
|
58 | 62 |
|
@@ -136,3 +140,22 @@ impl Execution {
|
136 | 140 | self
|
137 | 141 | }
|
138 | 142 | }
|
| 143 | + |
| 144 | +/// Hard link an executable or copy it if that fails. |
| 145 | +/// |
| 146 | +/// We first try to hard link an executable to save space. If that fails (as on Windows with |
| 147 | +/// different mount points, issue #60), we copy. |
| 148 | +#[cfg(not(target_os = "macos"))] |
| 149 | +fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> { |
| 150 | + let from = from.as_ref(); |
| 151 | + let to = to.as_ref(); |
| 152 | + fs::hard_link(from, to).or_else(|_| fs::copy(from, to).map(|_| ())) |
| 153 | +} |
| 154 | + |
| 155 | +/// Copy an executable. |
| 156 | +/// |
| 157 | +/// On macOS, hard linking the executable leads to strange failures (issue #419), so we just copy. |
| 158 | +#[cfg(target_os = "macos")] |
| 159 | +fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> { |
| 160 | + fs::copy(from, to).map(|_| ()) |
| 161 | +} |
0 commit comments