On Unix, relative paths to the exe are interpreted after cd'ing to the current_dir, but on Windows they're interpreted before. Here's an example test (1 test file, and 1 little binary that the test needs to build) that demonstrates this if you run cargo test on the two different platforms:
src/lib.rs
#[test]
fn execute_binary_from_another_dir() {
// Run `cargo build` to make sure the associated `foo` binary gets built.
std::process::Command::new("cargo").arg("build").status().unwrap();
// Shell out to `foo`, just to confirm that this works fine.
std::process::Command::new("target/debug/foo")
.status()
.unwrap();
// Now try to shell out to `foo` again while also setting the current_dir.
// This fails on Unix, because the path to the binary is resolved *after*
// changing directories, but it works on Windows.
std::process::Command::new("target/debug/foo")
.current_dir("..")
.status()
.unwrap();
}
src/bin/foo.rs
fn main() {
println!("foo!");
}
I ran into a similar difference when I tried this with Python's subprocess.run(..., cwd=...). It looks like it's an artifact of Windows supporting an lpCurrentDirectory arg natively, while Unix has to fork and then chdir in the child before it calls exec. I prefer the semantics that we're getting on Windows right now*, but this issue is mainly that they're not the same.
* My main reason for preferring the current-Windows-style "current_dir does not affect the exe location" semantics: Emulating the current-Unix-style only requires a Path::join, which always works. But going the other way requires a Path::canonicalize, which can fail.
On Unix, relative paths to the exe are interpreted after cd'ing to the
current_dir, but on Windows they're interpreted before. Here's an example test (1 test file, and 1 little binary that the test needs to build) that demonstrates this if you runcargo teston the two different platforms:src/lib.rs
src/bin/foo.rs
I ran into a similar difference when I tried this with Python's
subprocess.run(..., cwd=...). It looks like it's an artifact of Windows supporting anlpCurrentDirectoryarg natively, while Unix has toforkand thenchdirin the child before it callsexec. I prefer the semantics that we're getting on Windows right now*, but this issue is mainly that they're not the same.* My main reason for preferring the current-Windows-style "
current_dirdoes not affect the exe location" semantics: Emulating the current-Unix-style only requires aPath::join, which always works. But going the other way requires aPath::canonicalize, which can fail.