diff --git a/CHANGELOG.md b/CHANGELOG.md index 098882a161..e271253915 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -177,6 +177,10 @@ statement and only call the static function instead. * The `--wrap-static-fns` option no longer emits wrappers for static variadic functions. +* Depfiles generated with `--depfile` or `Builder::depfile` will now be + properly generate module names and paths that include spaces by escaping + them. To make the escaping clear and consistent, backslashes are also + escaped. ## Removed diff --git a/bindgen/deps.rs b/bindgen/deps.rs index 987225b28e..2edeaa8886 100644 --- a/bindgen/deps.rs +++ b/bindgen/deps.rs @@ -9,12 +9,53 @@ pub(crate) struct DepfileSpec { impl DepfileSpec { pub fn write(&self, deps: &BTreeSet) -> std::io::Result<()> { - let mut buf = format!("{}:", self.output_module); + std::fs::write(&self.depfile_path, &self.to_string(deps)) + } + + fn to_string(&self, deps: &BTreeSet) -> String { + // Transforms a string by escaping spaces and backslashes. + let escape = |s: &str| s.replace('\\', "\\\\").replace(' ', "\\ "); + let mut buf = format!("{}:", escape(&self.output_module)); for file in deps { - buf = format!("{} {}", buf, file); + buf = format!("{} {}", buf, escape(file)); } + buf + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn escaping_depfile() { + let spec = DepfileSpec { + output_module: "Mod Name".to_owned(), + depfile_path: PathBuf::new(), + }; - std::fs::write(&self.depfile_path, &buf) + let deps: BTreeSet = vec![ + r"/absolute/path".to_owned(), + r"C:\win\absolute\path".to_owned(), + r"../relative/path".to_owned(), + r"..\win\relative\path".to_owned(), + r"../path/with spaces/in/it".to_owned(), + r"..\win\path\with spaces\in\it".to_owned(), + r"path\with/mixed\separators".to_owned(), + ] + .into_iter() + .collect(); + assert_eq!( + spec.to_string(&deps), + "Mod\\ Name: \ + ../path/with\\ spaces/in/it \ + ../relative/path \ + ..\\\\win\\\\path\\\\with\\ spaces\\\\in\\\\it \ + ..\\\\win\\\\relative\\\\path \ + /absolute/path \ + C:\\\\win\\\\absolute\\\\path \ + path\\\\with/mixed\\\\separators" + ); } }