diff --git a/binaries/cli/src/template/c/mod.rs b/binaries/cli/src/template/c/mod.rs index 7dbf56379a..c89627ec93 100644 --- a/binaries/cli/src/template/c/mod.rs +++ b/binaries/cli/src/template/c/mod.rs @@ -80,7 +80,7 @@ fn create_cmakefile(root: PathBuf, use_path_deps: bool) -> Result<(), eyre::ErrR const CMAKEFILE: &str = include_str!("cmake-template.txt"); let cmake_file = if use_path_deps { - CMAKEFILE.replace("__DORA_PATH__", super::workspace_dir()?) + CMAKEFILE.replace("__DORA_PATH__", &super::workspace_dir()?) } else { CMAKEFILE.replace("__DORA_PATH__", "") }; @@ -136,7 +136,7 @@ fn create_node_cmakefile( let cmake_content = if use_path_deps { NODE_CMAKE .replace("___name___", name) - .replace("__DORA_PATH__", super::workspace_dir()?) + .replace("__DORA_PATH__", &super::workspace_dir()?) } else { NODE_CMAKE .replace("___name___", name) diff --git a/binaries/cli/src/template/cxx/mod.rs b/binaries/cli/src/template/cxx/mod.rs index b486d6c41f..ee16372b7e 100644 --- a/binaries/cli/src/template/cxx/mod.rs +++ b/binaries/cli/src/template/cxx/mod.rs @@ -79,7 +79,7 @@ fn create_cmakefile(root: PathBuf, use_path_deps: bool) -> Result<(), eyre::ErrR const CMAKEFILE: &str = include_str!("cmake-template.txt"); let cmake_file = if use_path_deps { - CMAKEFILE.replace("__DORA_PATH__", super::workspace_dir()?) + CMAKEFILE.replace("__DORA_PATH__", &super::workspace_dir()?) } else { CMAKEFILE.replace("__DORA_PATH__", "") }; @@ -132,7 +132,7 @@ fn create_node_cmakefile( let cmake_content = if use_path_deps { NODE_CMAKE .replace("___name___", name) - .replace("__DORA_PATH__", super::workspace_dir()?) + .replace("__DORA_PATH__", &super::workspace_dir()?) } else { NODE_CMAKE .replace("___name___", name) diff --git a/binaries/cli/src/template/mod.rs b/binaries/cli/src/template/mod.rs index cc6b03dbd9..23b0a8cfd0 100644 --- a/binaries/cli/src/template/mod.rs +++ b/binaries/cli/src/template/mod.rs @@ -9,14 +9,38 @@ mod rust; /// Path to the dora workspace root (two levels above the CLI crate /// manifest), used by the C/C++ templates to reference dora via path /// dependencies when `use_path_deps` is set. -fn workspace_dir() -> eyre::Result<&'static str> { - Path::new(env!("CARGO_MANIFEST_DIR")) +fn workspace_dir() -> eyre::Result { + let dir = Path::new(env!("CARGO_MANIFEST_DIR")) .parent() .context("Could not get manifest parent folder")? .parent() .context("Could not get manifest grandparent folder")? .to_str() - .context("dora workspace path is not valid UTF-8") + .context("dora workspace path is not valid UTF-8")?; + Ok(normalize_for_cmake(dir)) +} + +// CMake treats `\` as a string escape character, so a raw Windows path +// (e.g. `C:\Users\...`) substituted into CMakeLists.txt fails to parse. +// Both CMake and Windows accept `/`, so normalize before substitution. +fn normalize_for_cmake(path: &str) -> String { + path.replace('\\', "/") +} + +#[cfg(test)] +mod tests { + use super::*; + + // Uses a hardcoded Windows-style sample path rather than the live + // `workspace_dir()` output, since on Linux/macOS CI runners the real + // path never contains a backslash and the assertion would pass + // trivially without exercising the normalization at all. + #[test] + fn normalize_for_cmake_replaces_backslashes() { + let normalized = normalize_for_cmake(r"C:\Users\example\dora"); + assert_eq!(normalized, "C:/Users/example/dora"); + assert!(!normalized.contains('\\')); + } } pub fn create(args: crate::CommandNew, use_path_deps: bool) -> eyre::Result<()> {