in src/compiler/nvcc.rs [1117:1217]
fn remap_generated_filenames(
args: &[String],
old_to_new: &mut HashMap<String, String>,
ext_counts: &mut HashMap<String, i32>,
) -> Vec<String> {
args.iter()
.map(|arg| {
// Special case for MSVC's preprocess output file name flag
let arg_is_msvc_preprocessor_output = arg.starts_with("-Fi");
let arg = if arg_is_msvc_preprocessor_output {
arg.trim_start_matches("-Fi").to_owned()
} else {
arg.to_owned()
};
// If the argument doesn't start with `-` and is a file that
// ends in one of the below extensions, rename the file to an
// auto-incrementing stable name
let maybe_extension = (!arg.starts_with('-'))
.then(|| {
[
".cpp1.ii",
".cpp4.ii",
".cudafe1.c",
".cudafe1.cpp",
".cudafe1.stub.c",
]
.iter()
.find(|ext| arg.ends_with(*ext))
.copied()
})
.unwrap_or(None);
// If the argument is a file that ends in one of the above extensions:
// * If it's our first time seeing this file, create a unique name for it
// * If we've seen this file before, lookup its unique name in the hash map
//
// This ensures stable names are in cudafe++ output and #include directives,
// eliminating one source of false-positive cache misses.
let arg = match maybe_extension {
Some(extension) => {
old_to_new
.entry(arg)
.or_insert_with_key(|arg| {
// Initialize or update the number of files with a given extension:
// compute_70.cudafe1.stub.c -> x_0.cudafe1.stub.c
// compute_60.cudafe1.stub.c -> x_1.cudafe1.stub.c
// etc.
let count = ext_counts
.entry(extension.into())
.and_modify(|c| *c += 1)
.or_insert(0)
.to_string();
// Return `/tmp/dir/x_{count}.{ext}` as the new name, i.e. `/tmp/dir/x_0.cudafe1.stub.c`
PathBuf::from(arg)
.parent()
.unwrap_or(Path::new(""))
// Don't use the count as the first character of the file name, because the file name
// may be used as an identifier (via the __FILE__ macro) and identifiers with leading
// digits are not valid in C/C++, i.e. `x_0.cudafe1.cpp` instead of `0.cudafe1.cpp`.
.join("x_".to_owned() + &count + extension)
.to_string_lossy()
.to_string()
})
.to_owned()
}
None => {
// If the argument isn't a file name with one of our extensions,
// it may _reference_ files we've renamed. Go through and replace
// all old names with their new stable names.
//
// Sort by string length descending so we don't accidentally replace
// `zzz.cudafe1.cpp` with the new name for `zzz.cudafe1.c`.
//
// For example, if we have these renames:
//
// compute_70.cudafe1.cpp -> x_0.cudafe1.cpp
// compute_70.cudafe1.c -> x_2.cudafe1.c
//
// `compute_70.cudafe1.cpp` should be replaced with `x_0.cudafe1.cpp`, not `x_2.cudafe1.c`
//
let mut arg = arg.clone();
for (old, new) in old_to_new
.iter()
.sorted_by(|a, b| b.0.len().cmp(&a.0.len()))
{
arg = arg.replace(old, new);
}
arg
}
};
if arg_is_msvc_preprocessor_output {
format!("-Fi{}", arg)
} else {
arg
}
})
.collect::<Vec<_>>()
}