|
56 | 56 | #![allow(deprecated)]
|
57 | 57 | #![deny(missing_docs)]
|
58 | 58 |
|
59 |
| -use std::collections::HashMap; |
| 59 | +use std::collections::{hash_map, HashMap}; |
60 | 60 | use std::env;
|
61 | 61 | use std::ffi::{OsStr, OsString};
|
62 | 62 | use std::fmt::{self, Display, Formatter};
|
63 | 63 | use std::fs;
|
| 64 | +use std::hash::Hasher; |
64 | 65 | use std::io::{self, BufRead, BufReader, Read, Write};
|
65 | 66 | use std::path::{Component, Path, PathBuf};
|
66 | 67 | use std::process::{Child, Command, Stdio};
|
@@ -1023,7 +1024,24 @@ impl Build {
|
1023 | 1024 |
|
1024 | 1025 | let mut objects = Vec::new();
|
1025 | 1026 | for file in self.files.iter() {
|
1026 |
| - let obj = dst.join(file).with_extension("o"); |
| 1027 | + let obj = if file.has_root() { |
| 1028 | + // If `file` is an absolute path, prefix the `basename` |
| 1029 | + // with the `dirname`'s hash to ensure name uniqueness. |
| 1030 | + let basename = file |
| 1031 | + .file_name() |
| 1032 | + .ok_or_else(|| Error::new(ErrorKind::InvalidArgument, "file_name() failure"))? |
| 1033 | + .to_string_lossy(); |
| 1034 | + let dirname = file |
| 1035 | + .parent() |
| 1036 | + .ok_or_else(|| Error::new(ErrorKind::InvalidArgument, "parent() failure"))? |
| 1037 | + .to_string_lossy(); |
| 1038 | + let mut hasher = hash_map::DefaultHasher::new(); |
| 1039 | + hasher.write(dirname.to_string().as_bytes()); |
| 1040 | + dst.join(format!("{:016x}-{}", hasher.finish(), basename)) |
| 1041 | + .with_extension("o") |
| 1042 | + } else { |
| 1043 | + dst.join(file).with_extension("o") |
| 1044 | + }; |
1027 | 1045 | let obj = if !obj.starts_with(&dst) {
|
1028 | 1046 | dst.join(obj.file_name().ok_or_else(|| {
|
1029 | 1047 | Error::new(ErrorKind::IOError, "Getting object file details failed.")
|
|
0 commit comments